/*
hdoj 1175-连连看
written by lky
501994 2008-03-18 14:53:30 Accepted 1175 781MS 8868K 2269 B C++ lky
标准bfs+搜索记忆化,新结点的turn数小于在该方向上的turn数时才入队列
*/
#include <iostream>
#include <queue>
using namespace std;
#define MAX 999999
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int MAP[1001][1001];
int val[1001][1001][5];
int m, n, turn;
typedef struct
{
int x, y;
int direction;
int nturn;
}Node;
int main()
{
int nn;
int i, j, k;
Node s, t, tt;
int sx, sy, ex, ey;
queue<Node> q;
while (cin >> m >> n)
{
if (m == 0 && n == 0)
break;
turn = 2;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
cin >> MAP[i][j];
cin >> nn;
while (nn--)
{
int temp;
for (i = 0; i < m; i++)
for(j = 0; j < n; j++)
for(k = 1; k <= 4; k++)
val[i][j][k] = MAX;
cin >> sx >> sy >> ex >> ey;
sy--, sx--, ey--, ex--;
//判断同一个点
if (sx == ex && sy == ey)
{
cout << "YES" << endl;
continue;
}
//判断不是同一种类
if (MAP[sx][sy] != MAP[ex][ey])
{
cout << "NO" << endl;
continue;
}
//判断有至少有一个没有棋子
if (MAP[sx][sy] == 0 || MAP[ex][ey] == 0)
{
cout << "NO" << endl;
continue;
}
temp = MAP[ex][ey];
MAP[ex][ey] = 0;
bool flag = false;
s.x = sx, s.y = sy, s.nturn = 0, s.direction = 0;
for (i = 1; i <= 4; i++)
val[s.x][s.y][i] = 0;
q.push(s);
while (!q.empty())
{
t = q.front();
q.pop();
if (t.x == ex && t.y == ey && t.nturn <= turn)
{
flag = true;
break;
}
for (i = 0; i < 4; i++)
{
tt.x = t.x + dir[i][0];
tt.y = t.y + dir[i][1];
tt.direction = t.direction;
tt.nturn = t.nturn;
if (MAP[tt.x][tt.y] == 0 && tt.x>=0&&tt.x<m && tt.y>=0&&tt.y<n)
{
if (tt.direction == 0) //第一次
{
tt.direction = i + 1;
}
else if (tt.direction != i + 1) // 转弯
{
tt.direction = i + 1;
tt.nturn++;
}
if (tt.nturn < val[tt.x][tt.y][tt.direction] && tt.nturn <= turn)
{
val[tt.x][tt.y][tt.direction] = tt.nturn;
q.push(tt);
}
}
}
}
while (!q.empty())
{
q.pop();
}
if (flag)
{
cout << "YES" << endl;
}
else
cout << "NO" << endl;
MAP[ex][ey] = temp;
}
}
return 0;
}
hdoj 1175-连连看
written by lky
501994 2008-03-18 14:53:30 Accepted 1175 781MS 8868K 2269 B C++ lky
标准bfs+搜索记忆化,新结点的turn数小于在该方向上的turn数时才入队列
*/
#include <iostream>
#include <queue>
using namespace std;
#define MAX 999999
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
int MAP[1001][1001];
int val[1001][1001][5];
int m, n, turn;
typedef struct
{
int x, y;
int direction;
int nturn;
}Node;
int main()
{
int nn;
int i, j, k;
Node s, t, tt;
int sx, sy, ex, ey;
queue<Node> q;
while (cin >> m >> n)
{
if (m == 0 && n == 0)
break;
turn = 2;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
cin >> MAP[i][j];
cin >> nn;
while (nn--)
{
int temp;
for (i = 0; i < m; i++)
for(j = 0; j < n; j++)
for(k = 1; k <= 4; k++)
val[i][j][k] = MAX;
cin >> sx >> sy >> ex >> ey;
sy--, sx--, ey--, ex--;
//判断同一个点
if (sx == ex && sy == ey)
{
cout << "YES" << endl;
continue;
}
//判断不是同一种类
if (MAP[sx][sy] != MAP[ex][ey])
{
cout << "NO" << endl;
continue;
}
//判断有至少有一个没有棋子
if (MAP[sx][sy] == 0 || MAP[ex][ey] == 0)
{
cout << "NO" << endl;
continue;
}
temp = MAP[ex][ey];
MAP[ex][ey] = 0;
bool flag = false;
s.x = sx, s.y = sy, s.nturn = 0, s.direction = 0;
for (i = 1; i <= 4; i++)
val[s.x][s.y][i] = 0;
q.push(s);
while (!q.empty())
{
t = q.front();
q.pop();
if (t.x == ex && t.y == ey && t.nturn <= turn)
{
flag = true;
break;
}
for (i = 0; i < 4; i++)
{
tt.x = t.x + dir[i][0];
tt.y = t.y + dir[i][1];
tt.direction = t.direction;
tt.nturn = t.nturn;
if (MAP[tt.x][tt.y] == 0 && tt.x>=0&&tt.x<m && tt.y>=0&&tt.y<n)
{
if (tt.direction == 0) //第一次
{
tt.direction = i + 1;
}
else if (tt.direction != i + 1) // 转弯
{
tt.direction = i + 1;
tt.nturn++;
}
if (tt.nturn < val[tt.x][tt.y][tt.direction] && tt.nturn <= turn)
{
val[tt.x][tt.y][tt.direction] = tt.nturn;
q.push(tt);
}
}
}
}
while (!q.empty())
{
q.pop();
}
if (flag)
{
cout << "YES" << endl;
}
else
cout << "NO" << endl;
MAP[ex][ey] = temp;
}
}
return 0;
}