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;}