思路:剪枝+dfs
我们把map的奇偶性以01编号:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
我们发现从0走一步一定走到1,从1走一步一定走到0。
也就是说,如果当前的狗所在的坐标与D的坐标奇偶性不一样,那么狗需要走奇数步。
同理,如果狗所在坐标与D的坐标奇偶性一样,那么狗需要走偶数步数。
也就是说,狗的坐标x、y和对2取余是它的奇偶性,Dxy和对2取余是D的奇偶性。
两个奇偶性一加再对2取余,拿这个余数去与剩下时间对2取余的余数作比较即可。
1 /* 2 Name:hdu-1010-Tempter of the Bone 3 Copyright: 4 Author: 5 Date: 2018/4/25 11:14:12 6 Description: 7 */ 8 #include <iostream> 9 #include <cstring> 10 #include <cstdio> 11 #include <algorithm> 12 using namespace std; 13 int n, m ,t, flag, ex, ey, sx, sy; 14 int dir[4][2] = {1,0,-1,0,0,1,0,-1}; 15 char map[10][10]; 16 int vis[10][10]; 17 void dfs(int x, int y, int steps) { 18 if (steps > t) return ; 19 if (x == ex && y == ey && steps == t) { 20 flag = 1; 21 return; 22 } 23 for (int i=0; i<4; i++) { 24 int xx = x + dir[i][0]; 25 int yy = y + dir[i][1]; 26 if (xx >= n || yy >=m || xx<0 || yy<0) continue; 27 if (map[xx][yy] == 'X' || vis[xx][yy]) continue; 28 vis[xx][yy] = 1; 29 dfs(xx, yy, steps+1); 30 vis[xx][yy] = 0; 31 if (flag) return ;//剪枝 32 } 33 } 34 int main() 35 { 36 // freopen("in.txt", "r", stdin); 37 while (cin>>n>>m>>t, n+m+t) { 38 getchar(); 39 memset(vis, 0, sizeof(vis)); 40 memset(map, 0, sizeof(map)); 41 flag = 0; 42 int wall = 0; 43 for (int i=0; i<n; i++) { 44 scanf("%s", map[i]); 45 for (int j=0; j<m; j++) { 46 if (map[i][j] == 'S') { 47 sx = i, sy =j; 48 } 49 if (map[i][j] == 'D') { 50 ex = i, ey =j; 51 } 52 if (map[i][j] == 'X') { 53 wall++; 54 } 55 } 56 } 57 if (abs(ex - sx) + abs(ey - sy) > t || (ex+ey+sx+sy+t)%2 == 1) {//路径剪枝+奇偶剪枝 58 cout<<"NO "; 59 continue; 60 } 61 if (n*m-wall < t) { 62 cout<<"NO "; 63 continue; 64 } 65 vis[sx][sy] = 1; 66 dfs(sx, sy, 0); 67 if (flag == 0) { 68 cout<<"NO "; 69 } else { 70 cout<<"YES "; 71 } 72 } 73 return 0; 74 }