就是连连看游戏。开始用优先队列广搜,WA,跟海峰讨论了一下,发现只要一次走一行,就可以只用普通队列即可,又是一道泪流满面的题目啊~~~~~
/*
* hdu1175/win.cpp
* Created on: 2011-10-2
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int MAXN = 1010;
int map[MAXN][MAXN];
bool visited[MAXN][MAXN][4];
int M, N;
const int move[4][2] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
typedef struct MyPoint {
int x, y;
int dire, turn;
} MyPoint;
void init() {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
scanf("%d", &map[i][j]);
}
}
}
bool BFS(int x1, int y1, int x2, int y2) {
queue<MyPoint> que;
MyPoint tmp, cur;
tmp.x = x1;
tmp.y = y1;
tmp.dire = -1;
tmp.turn = -1;
que.push(tmp);
memset(visited, false, sizeof(visited));
for (int i = 0; i < 4; i++) {
visited[x1][y1][i] = true;
}
while (!que.empty()) {
cur = que.front();
que.pop();
if (cur.turn > 2) {
continue;
}
for (int j = 0; j < 4; j++) {
tmp.turn = cur.turn;
if (cur.dire != j) {
tmp.turn++;
}
for (int k = 1;; k++) {
tmp.x = cur.x + move[j][0] * k;
tmp.y = cur.y + move[j][1] * k;
if (tmp.x <= 0 || tmp.y <= 0 || tmp.x > N || tmp.y > M) {
break;
}
if (tmp.x == x2 && tmp.y == y2) {
if (tmp.turn <= 2) {
return true;
} else {
break;
}
}
if (map[tmp.x][tmp.y] > 0 || visited[tmp.x][tmp.y][j]) {
break;
}
tmp.dire = j;
que.push(tmp);
visited[tmp.x][tmp.y][j] = true;
}
}
}
return false;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int Q, x1, y1, x2, y2;
while (scanf("%d%d", &N, &M) == 2) {
if (N == 0 && M == 0) {
break;
}
init();
scanf("%d", &Q);
for (int i = 0; i < Q; i++) {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if (!map[x1][y1] || !map[x2][y2] || map[x1][y1] != map[x2][y2]) {
puts("NO");
continue;
}
if (BFS(x1, y1, x2, y2)) {
puts("YES");
} else {
puts("NO");
}
}
}
return 0;
}