题目链接: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; }