Tempter of the Bone HDU - 1010
考察:dfs+剪枝
错误思路:
用bfs解此题,会WA,因为我们要时间为T时刚刚好到达,bfs是最短时间.这道题需要我们在D周围绕圈子
思路:
直接暴力TLE了.所以需要一些剪枝.
- 当时间==T时回溯
- 这个剪枝比较关键,奇偶剪枝,如果S坐标之和的奇偶与D奇偶相同,说明我们到达D需要偶数步,奇偶不同需要奇数步.不管怎么绕圈子都是一样.
这位大佬的证明比较详细 GO
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N = 8; 6 int n,m,T; 7 int xx[4] ={-1,1,0,0},yy[4] = {0,0,-1,1}; 8 char mp[N][N]; 9 bool st[N][N]; 10 bool dfs(int x,int y,int t) 11 { 12 if(t==T) 13 { 14 if(mp[x][y]=='D') return 1; 15 return 0; 16 } 17 for(int i=0;i<4;i++) 18 { 19 int dx = x+xx[i],dy = y+yy[i]; 20 if(dx>0&&dx<=n&&dy>0&dy<=m&&mp[dx][dy]!='X'&&!st[dx][dy]) 21 { 22 st[dx][dy] = 1; 23 if(dfs(dx,dy,t+1)) return 1; 24 st[dx][dy] = 0; 25 } 26 } 27 st[x][y] = 1; 28 return 0; 29 } 30 int main() 31 { 32 while(scanf("%d%d%d",&n,&m,&T)!=EOF&&n) 33 { 34 int x,y,ex,ey; 35 for(int i=1;i<=n;i++) 36 scanf("%s",mp[i]+1); 37 for(int i=1;i<=n;i++) 38 for(int j=1;j<=m;j++) 39 { 40 st[i][j] = 0; 41 if(mp[i][j]=='S') x = i,y = j; 42 else if(mp[i][j]=='D') ex = i,ey = j; 43 } 44 int t = (x+y)&1,k = (ex+ey)&1; 45 if(t!=k&&!(T&1)) {puts("NO");continue;} 46 if(t==k&&(T&1)) {puts("NO");continue;} 47 st[x][y] = 1; 48 if(dfs(x,y,0)) puts("YES"); 49 else puts("NO"); 50 } 51 return 0; 52 }