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

浙公网安备 33010602011771号