#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;
/*
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
*/
int maps[1001][1001],visit[1001][1001];
int n,m;
int xx1,x2,yy1,y2;
int t[4][2]={-1,0,1,0,0,-1,0,1};
struct xh
{
int x,y;//坐标
int step;//拐弯次数
int distant;//上一次走的方向,判断拐弯
}w,ww;
bool panduan(int x,int y)
{
return x>=1&&x<=n&&y>=1&&y<=m;
}
void bfs()
{
queue<xh>q;
q.push(w);
while(!q.empty())
{
ww=q.front();
q.pop();
if(ww.step>2)
{
continue;
}
for(int i=0;i<4;i++)
{
w=ww;
w.x+=t[i][0];
w.y+=t[i][1];
w.distant=i;
if(panduan(w.x,w.y)&&(maps[w.x][w.y]==0||w.x==x2&&w.y==y2))
{
if(ww.distant!=520&&ww.distant!=w.distant)
w.step++;
if(w.step>2)
continue;
if(visit[w.x][w.y]>=w.step)//这个地方一定是大于等于,因为可能回搜
{
visit[w.x][w.y]=w.step;
q.push(w);
}
if(w.x==x2&&w.y==y2)
{
printf("YES\n");
return ;
}
}
}
}
printf("NO\n");
return ;
}
int main()
{
int i,j,k;
while(cin>>n>>m&&n+m)
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&maps[i][j]);
scanf("%d",&k);
while(k--)
{
scanf("%d%d%d%d",&xx1,&yy1,&x2,&y2);
if(maps[xx1][yy1]!=maps[x2][y2]||maps[xx1][yy1]==0)//不是同一个数或为0,直接输出NO
{
printf("NO\n");
continue;
}
memset(visit,1,sizeof(visit));//将visit初始化大一些
w.x=xx1;
w.y=yy1;
w.step=0;
w.distant=520;//初始化方向
visit[w.x][w.y]=0;
bfs();
}
}
return 520;
}
题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1175
广搜(bfs)
主要问题是记录拐弯次数,比较上一次和这一次的方向,方向相同拐弯次数不变,不同+1。
广搜有重复,所以用到一个技巧,将visit初始化大一些,当前拐弯次数小于visit时,才将当前拐弯次数赋值给visit,然后push。
题目代码如下:很清晰