yes
广搜题目,其实用深搜也可以做。
我刚开始向这道题 方向判断用两个数来代替,0代表列向,1代表横向。
然后根据dis数组赋值为 左、上、右、下,这样i%2==0时则是列向行走,i%2==1时为横向行走
经过实践证明,这么做时错误的。。o(╯□╰)o啊~~~~
好吧,关键在于,判断一个点可以不可以走,不仅看它是否在界内或者是否是墙。
而是看曾经到达这个点的转弯次数是否大于此次到达这个点的转弯次数。
因此,如果曾经到达这个点最小转弯次数等于这次到达这个点最小转弯次数。
那也要将这个点入队列。
就是说->到达一个点的转弯次数相同,但两次的方向可能不同。
So,如果用两个方向来代替四个方向,则无法实现这种情况。
And,End
/*
Author:Tree
From: http://blog.csdn.net/lttree
逃离迷宫
hdu 1728
BFS——广度优先搜索
迷宫转弯次数限定
*/
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
struct Coor
{
int x,y,fx,tn;
};
int n,m,turn,f_x,f_y,dis[4][2]={-1,0,0,-1,1,0,0,1};
char mapp[101][101];
int vis[101][101];
bool isout(int x,int y)
{
if( x<1 || x>n || y<1 || y>m ) return 1;
if( mapp[x][y]==‘*‘ ) return 1;
return 0;
}
void bfs(int sx,int sy)
{
int i;
memset(vis,-1,sizeof(vis));
queue <Coor> q;
Coor pre,lst;
pre.x=sx;
pre.y=sy;
pre.fx=-1;
pre.tn=0;
vis[pre.x][pre.y]=0;
q.push(pre);
while( !q.empty() )
{
pre=q.front();
q.pop();
for(i=0;i<4;++i)
{
lst.x=pre.x+dis[i][0];
lst.y=pre.y+dis[i][1];
// 判断坐标是否越界或者撞墙等
if( isout(lst.x,lst.y) ) continue;
// 方向是否改变,-1代表它上一步是起点
if( pre.fx!=-1 && pre.fx!=i ) lst.tn=pre.tn+1;
else lst.tn=pre.tn;
if( lst.tn>turn ) continue;
if(lst.x==f_x && lst.y==f_y) {cout<<"yes"<<endl;return;}
// 如果曾经到这里转弯次数大于这次到这里转弯次数,则该点可再进队列
if( vis[lst.x][lst.y]==-1 || vis[lst.x][lst.y]>=lst.tn )
{
lst.fx=i;
vis[lst.x][lst.y]=lst.tn;
q.push(lst);
}
}
}
cout<<"no"<<endl;
}
int main()
{
int test,i,j,s_x,s_y;
cin>>test;
while(test--)
{
cin>>n>>m;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
cin>>mapp[i][j];
// 注意别扭的输入
cin>>turn>>s_y>>s_x>>f_y>>f_x;
bfs(s_x,s_y);
}
return 0;
}
ACM-BFS之逃离迷宫——hdu1728,布布扣,bubuko.com
原文:http://blog.csdn.net/lttree/article/details/24550751