hdu acm 1010
一、奇偶性剪枝
我们把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取余的余数作比较即可。
二、距离剪枝
矩阵的大小是N*M 墙的数量记为wall 如果能走的路的数量 N*M - wall 小于时间T,就是说走完也不能到总的时间的,这显然是错误的,可以直接跳出了。
#include <iostream> #include <math.h> using namespace std; char maze[7][7]; int n, m, t, i, j; int sx, sy; int gx, gy; int d[7][7]; int dx[4] = {1, 0, -1, 0}; int dy[4] = {0, 1, 0, -1}; int flag, wall; void dfs(int x, int y, int time) { if(x == gx & y == gy) { if(time == t) flag = 1; return; } //剪枝 if(time >= t) return; for(int i=0; i<4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if(nx < n & 0 <= nx & ny < m & 0 <= ny & maze[nx][ny] != 'X') { maze[x][y] = 'X'; dfs(nx, ny, time + 1); maze[x][y] = '.'; //剪枝 if(flag) return; } } } int main() { while(cin >> n >> m >> t) { if(n==0 & m==0 & t==0) break; flag = 0; wall = 0; for(i=0; i<n; i++) { for(j=0; j<m; j++) { cin >> maze[i][j]; if(maze[i][j] == 'S') { sx = i; sy = j; } if(maze[i][j] == 'D') { gx = i; gy = j; } if(maze[i][j] == 'X') wall ++; } } //剪枝 if(n * m - wall < t) { cout << "NO" << endl; continue; } //剪枝 if(abs(sx-gx)+abs(sy-gy)>t||(sx+gx+sy+gy+t)%2==1) { cout << "NO" << endl; continue; } dfs(sx, sy, 0); if(flag) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }