bfs
本题要点:
1、连连看,先保证起点和终点,都不是0,且相等。
2、然后从起点 s 开始bfs, 用 step 记录拐弯次数。拐弯不超过两次。
3、direction 表示,进入点 (x, y) ,是从哪个方向进来的。
比如某一点 (x, y), 它的 direction == 0, 表示 (x, y)的上一点 是 从 左右方向进入 (x, y)。
此时,点(x, y) 的下一点,只需要从上下方向寻找。
4、点(x, y) 沿着上方向,一直走,直到不能走为止。所谓不能走,就是说,遇到非空白的地方。
当遇到 终点 t,表示可以找到一条路径(拐弯次数不超过2次), 从s到t。
代码较长,其中四个方向都是类似的代码。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
const int MaxN = 1010;
int n, m, query;
int mp[MaxN][MaxN];
bool vis[MaxN][MaxN];
struct node
{
int x, y, step;
int direction; //direction 表示,进入点 (x, y) ,是从哪个方向进来的
}; // direction == 0, 表示从 左右方向; direction == 0 表示从上下方向。 direction == -1, 表示点(x, y) 是起点
node s, t;
bool judge(int x, int y)
{
return x >= 1 && x <= n && y >= 1 && y <= m;
}
void bfs()
{
for(int i = 0; i <= n; ++i)
for(int j = 0; j <= m; ++j)
vis[i][j] = false;
int ax, ay;
node tmp;
s.step = -1, s.direction = -1;
queue<node> q;
q.push(s);
vis[s.x][s.y] = true;
while(q.size())
{
node now = q.front();q.pop();
ax = now.x, ay = now.y;
if(now.step >= 2) continue;
if(now.direction == -1 || now.direction == 1)// 往左,右
{
ax = now.x, ay = now.y;
while(true) // 往左
{
if(judge(ax, ay - 1) == false) break;
if(!(ax == t.x && ay - 1 == t.y) && mp[ax][ay - 1] == 0)
{
if(vis[ax][ay - 1] == false)
{
vis[ax][ay - 1] = true;
tmp.x = ax, tmp.y = ay - 1, tmp.direction = 0, tmp.step = now.step + 1;
q.push(tmp);
}
}else{
if(ax == t.x && ay - 1 == t.y)
{
printf("YES\n");
return;
}
break;
}
--ay;
}
ax = now.x, ay = now.y;
while(true)
{
if(judge(ax, ay + 1) == false) break;
if(!(ax == t.x && ay + 1 == t.y) && mp[ax][ay + 1] == 0)
{
if(vis[ax][ay + 1] == false)
{
vis[ax][ay + 1] = true;
tmp.x = ax, tmp.y = ay + 1, tmp.direction = 0, tmp.step = now.step + 1;
q.push(tmp);
}
}else{
if(ax == t.x && ay + 1 == t.y)
{
printf("YES\n");
return;
}
break;
}
++ay;
}
}
//往上,下
if(now.direction == -1 || now.direction == 0)
{
ax = now.x, ay = now.y;
while(true) // 上
{
if(judge(ax - 1, ay) == false) break;
if(!(ax - 1 == t.x && ay == t.y) && mp[ax - 1][ay] == 0)
{
if(vis[ax - 1][ay] == false)
{
vis[ax - 1][ay] = true;
tmp.x = ax - 1, tmp.y = ay, tmp.direction = 1, tmp.step = now.step + 1;
q.push(tmp);
}
}else{
if(ax - 1 == t.x && ay == t.y)
{
printf("YES\n");
return;
}
break;
}
--ax;
}
ax = now.x, ay = now.y;
while(true) // 下
{
if(judge(ax + 1, ay) == false) break;
if(!(ax + 1 == t.x && ay == t.y) && mp[ax + 1][ay] == 0)
{
if(vis[ax + 1][ay] == false)
{
vis[ax + 1][ay] = true;
tmp.x = ax + 1, tmp.y = ay, tmp.direction = 1, tmp.step = now.step + 1;
q.push(tmp);
}
}else{
if(ax + 1 == t.x && ay == t.y)
{
printf("YES\n");
return;
}
break;
}
++ax;
}
}
}
printf("NO\n");
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
if(0 == n && 0 == m) break;
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
scanf("%d", &mp[i][j]);
}
}
scanf("%d", &query);
for(int i = 0; i < query; ++i)
{
scanf("%d%d%d%d", &s.x, &s.y, &t.x, &t.y);
if(mp[s.x][s.y] == 0 || mp[t.x][t.y] == 0 || (mp[s.x][s.y] != mp[t.x][t.y]))
{
printf("NO\n");
}else
bfs();
}
}
return 0;
}
/*
3 4
1 2 3 4
0 0 0 0
4 3 2 1
4
1 1 3 4
1 1 2 4
1 1 3 3
2 1 2 4
3 4
0 1 4 3
0 2 4 1
0 0 0 0
2
1 1 2 4
1 3 2 3
0 0
*/
/*
YES
NO
NO
NO
NO
YES
*/