Tempter of the Bone(hdu1010,dfs)

来源:互联网 发布:北京设计软件培训 编辑:程序博客网 时间:2024/05/22 06:18

http://acm.hdu.edu.cn/showproblem.php?pid=1010

Tempter of the Bone

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 53685    Accepted Submission(s): 14458

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

 

Recommend

JGShining

解析:

题意:问一个人从指定的起点出发是否可以在指定的时间恰好到达目的地

思路:

dfs,由于是判断规定时间到达,所以不用bfs(开始的时候一直用bfs一直WA);

注意:

这里的dfs有几个小技巧要处理一下,否则不是会TLE

.奇偶剪枝,(原来不知道还有这种剪枝法就一直TLE):

由于在格子点1x1,y1,2(x2,y2),点1到达点2的最短距离是  

s=abs(x1-x2)+abs(y1-y2);

设预定达到时间为t

则:(t-s)%2=1,绝对不可达

     (t-s)%2==0,有可能到达;

以上结论可以这样理解,在最短路径附近折回走几步凑成t;

2.这里不用多设置一个vis数组,因为可以对已走的点在原图上标记为不可走的点,最后记得还原回来即可

3.return语句的慎用,以前一直以为return是跳出函数的意思;

可是在递归函数里它只是跳出一层递归而已;

这就是为什么dfs写成下面这样时会TLE了:

void dfs(int x,int y,int s)

{

if(x==tx&&y==ty&&s==t)

 {ok=1;

   return;

 }

if(s>t)

return;

if((t-s-(abs(x-tx)+abs(y-ty)))%2)return;

for(int i=0;i<4;i++)

{

int nx=x+d[i][0];

int ny=y+d[i][1];

if(nx>=0&&nx<n&&ny>=0&&ny<m&&map[nx][ny]!='X')

{

map[nx][ny]='X';

dfs(nx,ny,s+1);

map[nx][ny]='.';

}

}

}

156MS 260K 1131 B C++

*/

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include <iostream>using namespace std;const int N=10;int n,m,t,ok;int sx,sy,ty,tx;char map[N][N];int d[4][2]={{-1,0},{1,0},{0,1},{0,-1}};void dfs(int x,int y,int s){if(x==tx&&y==ty&&s==t) ok=1;if(ok)return;//已经找到结果if(s>t)return;if((t-s-(abs(x-tx)+abs(y-ty)))%2)return;//不可达for(int i=0;i<4;i++){int nx=x+d[i][0];int ny=y+d[i][1];if(nx>=0&&nx<n&&ny>=0&&ny<m&&map[nx][ny]!='X'){map[nx][ny]='X';dfs(nx,ny,s+1);map[nx][ny]='.';}}}int main(){int i,j;while(scanf("%d%d%d",&n,&m,&t)!=EOF){   if(m==0&&n==0&&t==0)     break;int step=0;for(i=0;i<n;i++) for(j=0;j<m;j++)   {   cin>>map[i][j];   if(map[i][j]=='S')   {sx=i;    sy=j;map[i][j]='X';//标记起始位置   }   else if(map[i][j]=='D')   {    tx=i;    ty=j;    step++;   }   else if(map[i][j]=='.'){step++;}   }   if(step<t)   {printf("NO\n");continue;   }  ok=0;   dfs(sx,sy,0);   printf("%s\n",ok==1? "YES":"NO");}return 0;}


小结:

其实去年就开始做这些题目了,可是当时也是半知半解,如今看了只不过是有了思路些

但是做起来的时候不免有参照了别人的代码,这是一种很不好的习惯,凡是不是自己尽心思考的答案就不会记住的。。。。。。。。。

Dfsbfs都是针对于数据比较下小的题目:

Dfs:

适合,寻找最长路径,最多点,找到组合数等,但是边界不好处理,省空间耗时间

Bdf:

适合:寻找最短路径,判断是否有路劲存在等,但是涉及队列,代码较长,省时间耗空间