险过。。
和胜利大逃亡差不多。。一样的道理。。
注意进行剪枝,不满足条件的直接NO,不进入dfs之中。。
#include"stdio.h"
#include"string.h"
#include"queue"
int map[1001][1001];
using namespace std;
int n,m,visit[1001][1001];
int sx,sy,ex,ey;
struct point
{
int x,y;
int step;
};
int judge(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=m&&(map[x][y]==0||(x==ex&&y==ey)))//别忘了,最后这个条件。。
return 1;
return 0;
}
int dir[4][2]={0,1, 0,-1, 1,0, -1,0};
int dfs()
{
int i,x,y;
queue<point>q;
point cur,next;
cur.x=sx,cur.y=sy;
cur.step=-1;
visit[sx][sy]=1;
q.push(cur);
while(!q.empty())
{
next=q.front();
q.pop();
if(next.step>2)//这个剪枝可以快四千多毫秒。。
return 0;
for(i=0;i<4;i++)
{
x=next.x+dir[i][0];
y=next.y+dir[i][1];
while(judge(x,y))
{
if(visit[x][y]==0)
{
cur.x=x;
cur.y=y;
cur.step=next.step+1;
q.push(cur);
if(cur.x==ex&&cur.y==ey&&cur.step<=2)//这个位置极其重要,若放在外边next后,则又会多搜好多而造成了超时。。在这里就accept。。
return 1;
visit[x][y]=1;
}
x=x+dir[i][0];
y=y+dir[i][1];
}
}
}
return 0;
}
int main()
{
int i,j,k;
while(scanf("%d%d",&n,&m),n||m)
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&map[i][j]);
scanf("%d",&k);
while(k--)
{
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
if(sx==ex&&sy==ey||map[sx][sy]==0||map[ex][ey]==0||map[sx][sy]!=map[ex][ey])//剪枝
{
printf("NO\n");
continue;
}
memset(visit,0,sizeof(visit));
if(dfs())
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}