HDU 1010 Tempter of the Bone 奇偶剪枝

来源:互联网 发布:山海经 美洲 知乎 编辑:程序博客网 时间:2024/06/16 00:02
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 5S.X...X...XD....3 4 5S.X...X....D0 0 0
Sample Output
NOYES

题意概括:给你一张n*m的地图,从S出发到D,X为墙,问是否能恰好在第t时刻到达D,走过的路会马上坍塌所以每个位置只能走一次。

解题思路:这题与普通的深搜区别在于不要求用时最少,只要对的时间,所以让坐标进入深搜之后的结束条件不是用时最少而是时间恰好符合要求。但是如果不剪枝的话超时,这时需要排除一些无用的数据。首先如果地图上减去墙剩下的点还没有时间多,也就是说就算把所以的点走完仍然有多余的时间,那么肯定无法在规定的时间到达。还有就是每到达一个新的坐标都需要考虑这个坐标与终点坐标的关系,如果该点与终点的距离大于剩下时间那么就算剩下的路没有任何障碍已无法在规定时间到达;而且该点坐标到终点的距离应该与所剩的时间同奇同偶。因为从一点到另一点的直线距离如果是奇数无论你如果绕最后的步数仍然是奇数,水平距离(奇数)不会改变,无论如何绕只要上去会下来这个过程的步数一定是偶数,那么偶数加上奇数还是奇数;相反偶数加偶数还是偶数。


代码:

#include<stdio.h>#include<string.h>int book[50][50],m,n,t,flag,l=0,l1=0,t1=0,x1,y1,x2,y2,f[50];int abs(int a){if(a<0)a=-a;return a;}char s1[50][50];void dfs(int x,int y,int step){//printf("%d %d %d\n",x,y,step);int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}};int j,k,tx,ty;if(flag==1)return ;if(x==x2&&y==y2&&step==t){//printf(",,%d\n",step);flag=1;return ;}int y5=abs(x-x2)+abs(y-y2);//printf("%d\n",y5);if(y5>t-step||(y5+t-step)%2!=0){return ;}for(k=0;k<=3;k++){l1++;tx=x+next[k][0];ty=y+next[k][1];if(tx>m||tx<1||ty>n||ty<1)continue;if(s1[tx][ty]=='.'&&book[tx][ty]==0){book[tx][ty]=1;dfs(tx,ty,step+1);book[tx][ty]=0;}}return ;}int main(){int i,j,k,p;while(scanf("%d%d%d",&m,&n,&t)!=EOF){flag=0;l1=0;if(m==0&&n==0&&t==0)break;x1=0;y1=0;memset(f,0,sizeof(f));memset(book,0,sizeof(book));getchar();p=0;for(i=1;i<=m;i++){scanf("\n");for(j=1;j<=n;j++){scanf("%c",&s1[i][j]);//printf("%c",s1[i][j]);if(s1[i][j]=='S'){x1=i;y1=j;}if(s1[i][j]=='D'){x2=i;y2=j;s1[i][j]='.';}if(s1[i][j]=='X')p++;}//printf("\n");}//printf("\n%d %d\n %d %d\n",x1,y1,x2,y2);if(m*n-p<=t){printf("NO\n");}else{book[x1][y1]=1;dfs(x1,y1,0);//printf("l1===%d\n",l1);//printf("%d\n",flag);if(flag==0){printf("NO");}else{printf("YES");}printf("\n");}getchar();}return 0;}


阅读全文
0 0
原创粉丝点击