概述:在一个棋盘中,放了很多的棋子。如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去。并且,棋子不能在棋盘外面走,你要做的是,给你一盘棋,请你判断给定的两个棋是否能消除。
思路:DFS,搜的过程要合理的“剪枝”,否则会超时,搜的时候,遇到不是同种的,或者都是0之类的可以直接PASS掉,以节约时间。
感想:不是特别难- =
#include<cstdio>
#include<cstring>
#include<iostream>
#include<fstream>
using namespace std;
int map[1010][1010], vis[1010][1010];
int dir[5][2] = {
{ 0, 0 },
{ 0, 1 },
{ -1, 0 },
{ 0, -1 },
{ 1, 0 } };
int m, n, a, b, dx, dy;
int dfs(int x, int y, int t, int times) {
if (times > 2)
return 0;
if (x == dx && y == dy)
return 1;
if (t > 0 && map[x][y] != 0)
return 0;
if (times == 2 && x != dx && y != dy)
return 0;
int i;
int tempx, tempy;
for (i = 1; i <= 4; ++i) {
tempx = x + dir[i][0];
tempy = y + dir[i][1];
if (vis[tempx][tempy] || tempx > m || tempx < 1 || tempy > n || tempy < 1)
continue;
vis[tempx][tempy] = 1;
if ((!t || t == i) && dfs(tempx, tempy, i, times))
return 1;
else if (t > 0 && t != i && dfs(tempx, tempy, i, times + 1))
return 1;
vis[tempx][tempy] = 0;
}
return 0;
}
int main()
{
//fstream cin("aaa.txt");
int i, j, q;
while (cin>>m>>n && m) {
for (i = 1; i <= m; ++i)
for (j = 1; j <= n; ++j)
cin >> map[i][j];
cin >> q;
while (q--) {
cin >> a >> b >> dx >> dy;
if (map[a][b] != map[dx][dy] || a > m || a < 1 || dx > m || dx < 1 || b > n || b < 1 || dy > n || dy < 1 || (a == dx && b == dy) || (map[a][b] == 0 && map[dx][dy] == 0)) {
printf("NO\n");
continue;
}
memset(vis, 0, sizeof(vis));
vis[a][b] = 1;
if (dfs(a, b, 0, 0))
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}