连连看
连连看

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <string>
#include <vector>
#include <deque>
#include <sstream>
using namespace std;
int h,l,n,bx,by,flag;
//int dir[8][2]={-1,-2,-2,-1,-2,1,-1,2,1,-2,2,-1,2,1,1,2};
int dir[4][2]={1,0,-1,0,0,1,0,-1};
bool vis[1002][1002];
int a[1002][1002];
void dfs(int x,int y,int dirc,int turn)
{
    if(turn>2||flag==1) return; //转弯两次以上或者已经找到
    if(turn==2&&(x-bx)!=0&&(y-by)!=0) return; //转弯两次时跟目标点不在同一条直线
    if(x==bx&&y==by&&turn<=2) //找到
    {
        flag=1;
        return;
    }
    for(int i=0;i<4;i++)
    {
        int xx=x+dir[i][0],yy=y+dir[i][1];
        if((xx>0&&xx<=h&&yy>0&&yy<=l&&a[xx][yy]==0&&vis[xx][yy]==0)||xx==bx&&yy==by) //判断,注意如果下一步走到目标点位时,并不符合条件,所以单独拿出一种情况
       {
            vis[xx][yy]=true;
            if(dirc==-1||dirc==i) //初始方向为-1,并不计入第一次转弯
            dfs(xx,yy,i,turn);
            else
            dfs(xx,yy,i,turn+1);
            vis[xx][yy]=false;
       }
    }
    return;
}
int main()
{
    int sx,sy;
    while(cin>>h>>l)
    {
        if(h==0&&l==0) break;
        for(int i=1;i<=h;i++)
            for(int j=1;j<=l;j++)
                cin>>a[i][j];
        cin>>n;
        while(n--)
        {
            flag=0;
            memset(vis,0,sizeof(vis));
            cin>>sx>>sy>>bx>>by;
            vis[sx][sy]=true;
            if(a[sx][sy]==a[bx][by]&&a[sx][sy]!=0&&a[bx][by]!=0) //起始点和结束点相等,并且都不为0
            dfs(sx,sy,-1,0);
            if(flag==1) cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
    }
    return 0;
}

相关文章: