HDU 1010 Tempter of the Bone (搜索 + 奇偶剪枝)

HDU 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的坐标奇偶性一样,那么狗需要走偶数步数。
参考博客: http://www.cnblogs.com/ziyi--caolu/archive/2013/02/08/2909325.html

就是说(  (sx + sy) % 2 + (ex + ey) % 2  ) %2  等于 1 的话表示奇偶性不同,等于0表示奇偶性相同。
而上式也可写成(sx + sy + ex + ey ) % 2。
狗需要走的步数的奇偶性就是T % 2,那么 (  (sx + sy + ex + ey ) % 2 + T % 2 ) % 2 等于1的话就表示不能到达。
而上式也可写成(sx + sy + ex + ey + T) % 2。

就这这样,下面是我丑陋的代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int N, M, T;
char map[10][10];
int  sx, sy, ex, ey;
int flag;
int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
void dfs(int x, int y, int time) {
	if(time == T) {
		if(x == ex && y == ey) flag = 1; 
		return;
	}
	else if(x == ex && y == ey) return;
	if(flag) return;
	else {
		int i;
		for(i = 0; i < 4 && !flag; i++) {
			int tx = x + dir[i][0];
			int ty = y + dir[i][1];
			if(tx >= 1 && tx <= N && ty >= 1 && ty <= M && map[tx][ty] != 'X') {
				map[tx][ty] = 'X';
				dfs(tx, ty, time + 1);
				map[tx][ty] = '.';
			} 
		}
	}
}
int main () {
	//freopen("input.txt", "r", stdin);
	while(~scanf("%d %d %d", &N, &M, &T) && N + M + T) {
		getchar();
		int i, j;
		for(i = 1; i <= N; i++) {
			for(j = 1; j <= M; j++) {
				scanf("%c", &map[i][j]);
				if(map[i][j] == 'S') {
					sx = i;
					sy = j;
					map[i][j] = 'X';
				}
				else if(map[i][j] == 'D') {
					ex = i;
					ey = j;
				}
			}
			getchar();
		}
		if(abs(sx - ex) + abs(sy - ey) > T || (sx + sy + ex + ey + T) % 2) {    //剪枝
			printf("NO\n");
			continue;
		}
		flag = 0;
		dfs(sx, sy, 0);
		if(flag) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}



你可能感兴趣的:(HDU 1010 Tempter of the Bone (搜索 + 奇偶剪枝))