http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1110
题意:
小狗从S出发要在T时到达D。
“X”是墙,”.”是空地,走过之后地就会下陷,不能往回走。
分析:
以前就看过,经典的。昨天拿出来写,dfs函数倒是很快写出来,但是用的不流畅,还有剪枝,有一个大概是我无法想到的啊…奇偶剪枝:
Temp=(T-t)-(abs(x-endx)+abs(y-endy))
(T-t) : 指的是还需要的步数
(abs(x-endx)+abs(y-endy)) :现在所在格子到目标格子的距离。
当temp<0或者temp为奇数时不可能到达。
若中间没有墙那么两者应该是d+x==T-t
d是当前点到目标点的最短路,x是扩展值、其所曾加的和必定是偶数
简单的dfs,困难的剪枝。>,<
不过最悲剧的不是剪枝,是剪枝之后的wa,
这就是奇葩的地方,数据太恶心了,输入的每组字符串要是带有多个空格。一个getchar(),解决不了。所以选择用scanf(“%s”,&map[i][1]);太nb了,一开始还不理解,从第2个位置开始存字符串,自己scanf还是不太熟。谢谢fzu的芒果点拨啊。
#include<stdio.h> #include <math.h> char map[10][10]; int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}}; int N,M,T,startx,starty,endx,endy,flag; void dfs(int x,int y,int t) { int i,temp; if(x>N||y>M||x<=0||y<=0) return; if(x==endx && y==endy && t==T) flag=1; if(flag==1) return ; temp=(T-t)-fabs(x-endx)-fabs(y-endy); if(temp<0||temp%2) return; for(i=0;i<4;i++) { if(map[x+dir[i][0]][y+dir[i][1]]!='X') { map[x+dir[i][0]][y+dir[i][1]]='X'; dfs(x+dir[i][0],y+dir[i][1],t+1); map[x+dir[i][0]][y+dir[i][1]]='.'; } } return; } int main() { int i,j,num; while(scanf("%d%d%d",&N,&M,&T)!=EOF) { num=0; flag=0; if(N==0&&M==0&&T==0) break; for(i=1;i<=N;i++) { // getchar(); scanf("%s",&map[i][1]); for(j=1;j<=M;j++) { // scanf("%c",&map[i][j]); if(map[i][j]=='S') {startx=i;starty=j;} if(map[i][j]=='D') {endx=i;endy=j;} if(map[i][j]=='X') {num++;} } } if(N*M-num<=T) {printf("NO\n");continue;} map[startx][starty]='X'; flag=0; dfs(startx,starty,0); if(flag==1) printf("YES\n"); else printf("NO\n"); } return 0; }