连连看

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
struct node
{
    int x, y;
    int t, d;
};
queue<node> q;
int n, m, map[1002][1002], prove;
int visit[1002][1002][4]; //记录第(i,j)个点4个方向是否已走过,0为未走过。
int qry, sx, sy, ex, ey;
int dx[4] = {0, -1, 0, 1};
int dy[4] = {1, 0, -1, 0};
int check(int x, int y)
{
    if(x < 1 || x > n || y < 1 || y > m)
        return 0;
    else
        return 1;
}
void BFS()
{
    while(!q.empty())
        q.pop();
    memset(visit, 0, sizeof(visit));
    node s, e;
    s.x = sx;  s.y = sy; 
    s.t = 0;   s.d = -1;
    q.push(s);
    while(!q.empty())
    {
        s = q.front();
        q.pop();
        if(s.t > 2)
            continue;
        if(s.x == ex && s.y == ey)
        {
            prove = 1;
            cout << "YES" << endl;
            break;
        }
        for(int i = 0; i < 4; i++)
        {
            e.x = s.x + dx[i];  e.y = s.y + dy[i];
            if(!check(e.x, e.y) || visit[s.x][s.y][i])  //该点该方向是否走过
                continue;
            if( map[e.x][e.y] == 0 || (e.x == ex && e.y == ey) )
            {
                if(s.d == -1 || i == s.d)
                {
                    e.d = i;
                    e.t = s.t;
                    q.push(e);
                    visit[s.x][s.y][i] = 1;  //该点该方向已走过
                }
                else
                {
                    e.d = i;
                    e.t = s.t + 1;
                    q.push(e);
                   visit[s.x][s.y][i] = 1;
                }
            }
        }
    }
}
int main()
{
    while(cin >> n >> m&&n&&m)
    {
        for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin >> map[i][j];
        cin >> qry;
        for(int i = 1; i <= qry; i++)
        {
            cin >> sx >> sy >> ex >> ey;
            prove = 0;
            if(map[sx][sy] == map[ex][ey] && map[sx][sy] != 0)  
               BFS();
 
            if(!prove)
                 cout << "NO" << endl;
        }
    }
    return 0;
}

你可能感兴趣的:(连连看)