题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175
类似于迷宫问题,主要就在转折的处理上,在这里可以有一个强剪枝,具体见代码。
参考博客:http://www.cnblogs.com/qiu520/p/3250167.html 感谢!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int map[1010][1010];
int tmap[1010][1010];
int n, m, q;
int x1, y1, x2, y2;
int flag;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; // 右下左上1234
void dfs(int x, int y, int chg, int d) {
if(flag) return ;
int i;
if(chg >= 3) return ;
if(chg == 2) {
//强剪枝 ,不然超时
if( d == 1 && x != x2 ||
d == 2 && y != y2 ||
d == 3 && x != x2 ||
d == 4 && y != y2) {
return ;
}
}
if(x == x2 && y == y2) {
flag = 1;
printf("YES\n");
return ;
}
for(i = 0; i < 4; i++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(tx < 1 || tx > n || ty < 1 || ty > m || tmap[tx][ty] != 0) {
continue;
}
tmap[tx][ty] = -1;
if(d == 0) {
dfs(tx, ty, chg, i + 1);
}
else {
if(d != i + 1) {
dfs(tx, ty, chg + 1, i + 1);
}
else {
dfs(tx, ty, chg, i + 1);
}
}
tmap[tx][ty] = 0; //不要忘记回溯,因为已经走过的地方下次还有可能走
}
}
int main() {
while(~scanf("%d %d", &n, &m) && m + n) {
int i, j;
for(i = 1; i <= n; i++) {
for(j = 1; j <= m; j++) {
scanf("%d", &map[i][j]);
}
}
scanf("%d", &q);
while(q--) {
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
memcpy(tmap, map, sizeof(map));
if(tmap[x1][y1] == 0 || tmap[x1][y1] != tmap[x2][y2]) { //首先看是否有数是否是两个相同的数
printf("NO\n");
continue;
}
else {
tmap[x2][y2] = 0; //以便最后可以走这里
}
flag = 0;
tmap[x1][y1] = -1;
dfs(x1, y1, 0, 0);
if(flag == 0) printf("NO\n");
}
}
return 0;
}