思路:
对于每次位置进行上下左右四个搜索,标记来的方向,如果相同翻转次数不增长。
注意turn==2时同行同列的情况下会有优化,vis数组标记到达当前位置最小转弯次数
PS:当时自己做死活不出,比赛时候怼了三发竟然出了,运气真不错
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
int n,m;
int vis[1005][1005];
int mp[1005][1005];
int x1,y1,x2,y2;
int yes=0;
void dfs(int x,int y,int step,int from)
{
if(yes)
return ;
if(x==x2&&y==y2)
{
yes=1;
return ;
}
if(mp[x][y]!=0)
return;
if(vis[x][y]==0)
{
vis[x][y]=step;
}
else
{
if(vis[x][y]<=step)
return ;
else
vis[x][y]=step;
}
if(step==2)
{
if(!(x2==x||y2==y))
return ;
if(x2==x)
{
if(y2>y)
{
for(int i=y;i<y2;i++)
{
if(mp[x][i]!=0)
return ;
}
yes=1;
return ;
}
else if(y2<y)
{
for(int i=y;i>y2;i--)
{
if(mp[x][i]!=0)
return ;
}
yes=1;
return ;
}
}
if(y2==y)
{
if(x2<x)
{
for(int i=x;i>x2;i--)
{
if(mp[i][y]!=0)
return ;
}
yes=1;
return ;
}
else if(x2>x)
{
for(int i=x;i<x2;i++)
{
if(mp[i][y]!=0)
return ;
}
yes=1;
return;
}
}
}
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
for(int i=0;i<4;i++)
{
if(yes)
return ;
int sx,sy;
sx=x+next[i][0];
sy=y+next[i][1];
if(sx<1||sx>n||sy<1||sy>m)
continue;
if(i==from)
{
dfs(x+next[i][0],y+next[i][1],step,i);
}
else
dfs(x+next[i][0],y+next[i][1],step+1,i);
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
break;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&mp[i][j]);
}
}
int q;
scanf("%d",&q);
while(q--)
{
memset(vis,0,sizeof(vis));
yes=0;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(mp[x1][y1]!=mp[x2][y2]||mp[x1][y1]==0)
{
printf("NO\n");
}
else
{
for(int i=0;i<4;i++)
{
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
dfs(x1+next[i][0],y1+next[i][1],0,i);
}
if(yes)
printf("YES\n");
else
printf("NO\n");
}
}
}
return 0;
}