深搜基础题,用到了奇偶剪枝。
把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的坐标奇偶性一样,那么狗需要走偶数步数。
就是说( (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;
}