Tempter of the Bone
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
题意概括:
大概就是小狗从S点走到D点吃骨头,而且D点只会在t时刻出现骨头,问小狗是否能够吃到骨头
解题思路:
这题是一道基本的深搜问题,但是时间会超限,然后就需要剪枝处理,这里主要说一下剪枝的问题,首先判断非墙壁的位置的数目是否大于给的时间大小,如果小于的话直接就可以不用考虑了,因为时间是固定的不能走重复的路。然后就是奇偶剪枝的考虑因为从一个点到另外一个点的步数的奇偶性永远都是固定的,无论怎么绕行,所以对于任意路线的一个任意位置到目的地的奇偶性与已走的步数的奇偶性相加必须和最短路径的奇偶性是一致的。就是当前位置到终点的步数v=abs(x-p)+abs(y-q);的奇偶性与限制所剩的步数t-step的奇偶性相同h=t-step-v;转化一下就是h%2==0.额外要考虑的就是所剩步数必须大于等于当前位置到目标位置最短步数的预留步数,就是t>=step+v;这样进行搜索,如果已走步数大于预留的t则肯定走不到了,意思是说给你3步让你走,可是出发点到目标位置的最短步数为4,这样直接就可以判断走不到了。
#include <stdio.h>
#include <string.h>
#include <math.h>
int flag;
int n,m,p,q,l,f,t;
int book[9][9];
char map[9][9];
void dfs(int x,int y,int step)
{
int k,i,j;
int tx,ty,v,h;
int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
if(x==p&&y==q&&step==t)
flag=1;
if(flag==1||step>=t)
return ;
v=abs(x-p)+abs(y-q);
h=t-step-v;
if(h<0||h%2!=0)
return ;
for(k=0;k<4;k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<1||tx>n||ty<1||ty>m)
continue ;
if(book[tx][ty]==0&&map[tx][ty]!='X')
{
book[tx][ty]=1;
dfs(tx,ty,step+1);
book[tx][ty]=0;
}
}
return ;
}
int main()
{
int i,j,k;
while(scanf("%d%d%d",&n,&m,&t),n!=0,m!=0,t!=0)
{
flag=k=0;
for(i=1;i<=n;i++)
{
scanf("%s",map[i]+1);
for(j=1;j<=m;j++)
{
if(map[i][j]=='S')
{
l=i;
f=j;
}
if(map[i][j]=='D')
{
p=i;
q=j;
}
if(map[i][j]=='#')
k++;
}
}
memset(book,0,sizeof(book));
book[l][f]=1;
if(n*m-k>=t)
dfs(l,f,0);
if(flag==1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
---------------------
作者:Robin_yy
来源:CSDN
原文:https://blog.csdn.net/ak201605050122/article/details/76423028
版权声明:本文为博主原创文章,转载请附上博文链接!