hdu 1011 Tempter of the Bone【DFS+奇偶性剪枝】
2016-03-12 14:18
393 查看
Tempter of the Bone
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 99139 Accepted Submission(s): 26876
Problem Description
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.
The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the
T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for
more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.
Input
The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the
maze layout, with each line containing M characters. A character is one of the following:
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.
The input is terminated with three 0's. This test case is not to be processed.
Output
For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
Sample Output
NO
YES
Author
ZHANG, Zheng
Source
ZJCPC2004
直接DFS+剪枝没有过、在网上学到了一个叫做奇偶性剪枝的技巧,get√
假如我们有一个4*4的图:
. . . . . . . . . . . . . . . .现在假如我们起点是(1,1),走向各个点的时间消耗为:
0 1 2 3 1 2 3 4 2 3 4 5 3 4 5 6我们再使得他们的时间消耗进行奇偶数判断:(0表示偶数,1表示奇数):
0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0设起点为(x,y),目标点为(ex,ey);
我们看的出来,从0--------0需要偶数步,从0--------------1需要奇数步、
如果abs(x-y)+abs(dx-dy)为偶数,则说明 abs(x-y) 和 abs(dx-dy)的奇偶性相同,需要走偶数步、(1)
如果abs(x-y)+abs(dx-dy)为奇数,则说明 abs(x-y) 和 abs(dx-dy)的奇偶性不同,需要走奇数步、(2)
如果我们知道了(从这个题目出发的结论)剩余步数,当前坐标和目标坐标。我们能够由(1)和(2)来判断从当前坐标到目标坐标的奇偶性x,这个时候不难理解,当前坐标到目标坐标的奇偶性和剩余步数的奇偶性一定要相同才有可能走到目标坐标。
AC代码:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> using namespace std; char a[10][10]; int vis[10][10]; int fx[4]={1,-1,0,0}; int fy[4]={0,0,1,-1}; int x,y,step; int flag; int n,m; int ex,ey; void dfs(int x,int y,int cur) { int tmp=step-cur-abs(x-ex)-abs(y-ey);//重要剪枝、奇偶性剪枝、 if(tmp<0||tmp%2==1) { return ; } if(flag==1)//简单剪枝1、如果找到了可行方案,回溯即可 { return ; } if(cur==step) { if(x==ex&&y==ey) { flag=1; //return ; } return ; } for(int i=0;i<4;i++) { int xx=x+fx[i]; int yy=y+fy[i]; if(xx>=0&&xx<n&&yy>=0&&yy<m&&vis[xx][yy]==0&&a[xx][yy]=='.'||a[xx][yy]=='D')//这里有坑,写成!='X'是会wa的,测试数据有坑.... { vis[xx][yy]=1; dfs(xx,yy,cur+1); if(flag==1)return ; vis[xx][yy]=0; } if(flag==1)return ;//简单剪枝2 } } int main() { while(~scanf("%d%d%d",&n,&m,&step)) { if(n==0&&m==0&&step==0)break; int x,y; for(int i=0;i<n;i++) { scanf("%s",a[i]); for(int j=0;j<m;j++) { if(a[i][j]=='S') { x=i; y=j; } if(a[i][j]=='D') { ex=i; ey=j; } } } flag=0; memset(vis,0,sizeof(vis)); dfs(x,y,0); if(flag==1) { printf("YES\n"); } else { printf("NO\n"); } } }
相关文章推荐
- HDU 1011 Starship Troopers 树形背包
- FFMPEG库引用的顺序在GCC编译时还有影响
- Windows 驱动开发 - 5
- 关于开源中国的代码托管
- Qt之鼠标随手画及画多边形
- 概念理解
- 【opencv】大津法二值化
- 高效的斐波那契数列实现
- jQuery(一)
- Java开发必会的Linux命令
- git 常用命令--详述
- ahu-557容斥原理
- Java读取操作word2003 word2007 word2010文档
- [Unity] 常用技巧收集
- phoneGap入门教程
- Java并发编程(一)
- SVN经常使用命令说明
- [转]World Wind学习总结一
- Java反射
- rebmuNyppaH.202