#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int board[1010][1010];
bool vis[1010][1010];
int sx,sy,ex,ey;
bool flag;
int n,m,q;
int dx[]= {1,-1,0,0};
int dy[]= {0,0,1,-1};
void dfs(int x, int y, int dir, int turns) {
if( flag ) {//已经找到就终止
return;
}
if(turns > 2) {//转弯次数大于2
return;
}
if(turns == 2 && ((x - ex) != 0) && ((y - ey) != 0)) //2次转弯后和目的地不在同一直线上,剪枝
return;
if(x == ex && y == ey && turns <= 2) {//找到了
flag = 1;
return;
}
for(int i = 0; i < 4; i++) {//开始四方向搜索
int xx = x + dx[i];
int yy = y + dy[i];
if(xx < 1 || xx > n || y < 1 || y > m )//越界了,不扩展
continue;
if(!vis[xx][yy] && (board[xx][yy] == 0 || (xx == ex && yy == ey)) ) {//可以扩展到的地方
vis[xx][yy] = 1;
if(dir == -1 || dir == i)
dfs(xx, yy, i, turns);//不转弯走或者在起点位置
else
dfs(xx, yy, i, turns+1);//转弯走
vis[xx][yy] = false;
}
}
}
int main() {
//freopen("data.in", "r", stdin);
while(scanf("%d%d", &n, &m)) {
if(n == 0 && m == 0)
break;
memset(board,0,sizeof(board));
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
scanf("%d",&board[i][j]);
scanf("%d",&q);
for(int i = 0; i <q; ++i) {
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
memset(vis,0,sizeof(vis));
if( (board[sx][sy] == 0) || (board[ex][ey] == 0) || (board[sx][sy] != board[ex][ey])) {
printf("NO\n");
continue;
}
flag = 0;//初始化
if(board[sx][sy] == board[ex][ey] && board[sx][sy])
dfs(sx,sy,-1,0);//将初始方向设为-1,这里是个技巧
if(flag)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}
HDU 1175连连看(DFS)
最新推荐文章于 2019-10-14 21:46:44 发布