http://acm.hdu.edu.cn/showproblem.php?pid=1010
剪枝:1能走的地板数小于所给时间,肯定走不过。
2狗达到门的时间和所给时间同奇偶性。
奇偶剪枝:http://blog.csdn.net/chyshnu/article/details/6171758
可以把map看成这样:
n0 1 0 1 0 1
n1 0 1 0 1 0
n0 1 0 1 0 1
n1 0 1 0 1 0
n0 1 0 1 0 1
n从为 0 的格子走一步,必然走向为 1 的格子
n从为 1 的格子走一步,必然走向为 0 的格子
n即:
n 0 ->1或1->0 必然是奇数步
0->0 走1->1 必然是偶数步这样我们在搜索的过程中,走一步进行一次判断,如果不符合上述条件 就可以直接舍弃。
ex和ey是目标坐标
int temp=(t-time)-abs(x-ex)-abs(y-ey);
if(temp<0||temp&1) return 0;
temp&1 就是取二进制的最后一位,如果是奇数那就是1,偶数就是0;
行相减的绝对值加列想减的绝对值可以看出他们在map中的值是否相等,如果不等,必是奇数,如果相等就是偶数。。
而t-time就是剩余步数。。
最后想减得到temp 。。。
temp<0显然不能走了,而如果temp为奇数也就是说违背上述条件,也不能走。
1 #include <iostream> 2 #include <cstdio> 3 char map[10][10]; 4 int N, M, T, t, starti, startj, doori, doorj; 5 bool flag; 6 int dir[4][2] = {{-1,0}, {0,1}, {1,0}, {0,-1}}; 7 void dfs(int x, int y, int t) 8 { 9 if (x == doori && y == doorj && t == T) 10 { 11 flag = true; 12 return; 13 } 14 int temp = T - t - abs(x - doori) - abs(y - doorj); //奇偶判断 15 if (temp < 0 || temp & 1) 16 return; 17 for (int i = 0; i < 4; ++i) 18 { 19 int fx = x + dir[i][0]; 20 int fy = y + dir[i][1]; 21 if (fx>=0 && fx<N && fy>=0 && fy<M && map[fx][fy] != 'X') 22 { 23 map[fx][fy] = 'X'; 24 dfs(fx, fy, t + 1); 25 if (flag) 26 return; 27 map[fx][fy] = '.'; //回溯 28 } 29 } 30 } 31 int main() 32 { 33 while (scanf("%d %d %d", &N, &M, &T) != EOF && N) 34 { 35 int wallnum = 0; 36 flag = false; 37 for (int i = 0; i < N; ++i) 38 for (int j = 0; j < M; ++j) 39 { 40 std::cin >> map[i][j]; 41 if (map[i][j] == 'S') 42 { 43 starti = i; 44 startj = j; 45 } 46 else if (map[i][j] == 'D') 47 { 48 doori = i; 49 doorj = j; 50 ++wallnum; 51 } 52 else if (map[i][j] == '.') 53 ++wallnum; 54 } 55 map[starti][startj] = 'X'; 56 if (wallnum >= T) 57 dfs(starti, startj, 0); 58 if (flag) 59 printf("YES\n"); 60 else 61 printf("NO\n"); 62 } 63 system("pause"); 64 return 0; 65 }