#include <string>
#include <vector>
#include <iostream>
using namespace std;
int n, m;
int a[1000][1000];
int vis[1000][1000];
int x1, y1, x2, y2;
int startA, endA;
int result;
struct T
{
int x;
int y;
};
vector<T> v;
vector<T>::iterator it;
void DFS(int x, int y)
{
if (x <= 0 || y <= 0 || x > n || y > m || vis[x][y]) {
return ;
}
struct T a;
a.x = x;
a.y = y;
v.push_back(a);
if (x == x2 && y == y2) {
int sum = 0;
int tempX, tempY;
it = v.begin();
struct T temp = *it;
tempX = temp.x;
tempY = temp.y;
for (it = v.begin(); it != v.end(); it++) {
temp = *it;
if (temp.x != tempX && temp.y != tempY) {
sum++;
tempX = temp.x;
tempY = temp.y;
}
}
if (sum <= 2) {
result = sum;
return;
}
}
vis[x][y] = 1;
DFS(x, y - 1);
DFS(x - 1, y);
DFS(x, y + 1);
DFS(x + 1, y);
vis[x][y] = 0;
}
int main(int argc, const char * argv[]) {
while (cin >> n >> m) {
if (n == 0 && m == 0) {
break;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
int q;
cin >> q;
for (int i = 0; i < q; i++) {
cin >> x1 >> y1 >> x2 >> y2;
startA = a[x1][y1];
endA = a[x2][y2];
if (startA != endA || startA == 0 || endA == 0) {
cout << "NO" << endl;
continue;
}
DFS(x1, y1);
if (result <= 2 && result > 0) {
cout << "YES" << endl;
}else {
cout << "NO" << endl;
}
}
}
return 0;
}
用DFS没通过,我才想着用BFS来解决此题,用队列queue来解决内存占用过多的问题,因为需要经常pop,所以用queue不会出现内存超限的问题。
#include <queue>
#include <iostream>
#include <string.h>
using namespace std;
#define MAXN 1010
#define MAXM 1010
//定义一个二维数组保存方向
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int n, m;
int q;
int x1, y1;
int x2, y2;
//OK的作用:标记功能,当找到可行解的时候就把OK标记为1
int OK = 0;
int a[MAXN][MAXM], vis[MAXN][MAXM];
struct positon
{
int preX, preY; //(preX, preY)上一个点的坐标
int x, y; //(x, y)当前点的坐标
int cnt; //走到当前点转折的次数
} now, eed;
int can(struct positon aa)
{
/** 之前的想法是只要不超出边界,下一个不为0并且下一个数和终点的数相等就可以往下走,但是这样的想法是错误的,
因为其它地方也可能会有和终点一样的数
if (aa.x <= 0 || aa.x > n || aa.y <= 0 || aa.y > m || vis[aa.x][aa.y] || (a[aa.x][aa.y] > 0 && a[aa.x][aa.y] != a[x2][y2]) )
{
return 0;
}
return 1;
*/
if (aa.x >= 1 && aa.x <= n && aa.y >= 1 && aa.y <= m
&& !vis[aa.x][aa.y] && (a[aa.x][aa.y] == 0 || (aa.x == x2 && aa.y == y2)))
return 1;
return 0;
}
void BFS()
{
queue<positon> Q;
now.x = x1;
now.y = y1;
now.preX = x1;
now.preY = y1;
now.cnt = 0;
memset(vis, 0, sizeof(vis));
Q.push(now);
vis[now.x][now.y] = 1;
while (!Q.empty())
{
now = Q.front();
Q.pop();
if (now.x == x2 && now.y == y2)
{
//找到终点,OK标记为1,并返回
OK = 1;
return;
//}
}
for (int i = 0; i < 4; i++)
{
eed.x = now.x + dir[i][0];
eed.y = now.y + dir[i][1];
eed.preX = now.x;
eed.preY = now.y;
eed.cnt = now.cnt;
if (can(eed))
{
if (eed.x != now.preX && eed.y != now.preY)
{
if (now.cnt == 2) continue;
eed.cnt += 1;
}
vis[eed.x][eed.y] = 1;
Q.push(eed);
}
}
}
}
int main(int argc, const char * argv[])
{
while (cin >> n >> m)
{
if (n == 0 && m == 0)
{
break;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
}
}
cin >> q;
for (int i = 0; i < q; i++)
{
OK = 0;
cin >> x1 >> y1 >> x2 >> y2;
if (a[x1][y1] != a[x2][y2] || a[x1][y1] == 0 || a[x2][y2] == 0)
{
//如果起点和终点不相同,或者起点与终点任意一点为0,就直接输出NO
cout << "NO" << endl;
continue;
}
BFS();
if (OK == 1)
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
}
return 0;
}