码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1728 逃离迷宫

时间:2015-04-16 09:06:23      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

以为这题和连连看一样水,就很开心的用了dfs然后tle了无数次,好吧,我bfs总行了吧,然后wa了无数次.................

之所以wa是因为在bfs的过程中有些点是可以重复加入队列的.

例如

1
3 3
..*
...
*.*
1 1 1 3 2

这组数据(行,列)

1 (1,1)→(1,2)→(2,2)→(2,3)要转2次弯;

2 (1,1)→(2,1)→(2,2)→(2,3)只转1次弯;所以应该输出yes;

从上面的数据可以看出2次搜索都搜索到了(2,2)这个点,但是2次搜索到改点时的状态却不一样,1中经过该点时转了2次弯,而2种经过该点时却是转了1次弯,因此虽然(2,2)已走过,由于2中的状态要优于1中的状态(转弯次数较小),我们再次搜索到该点时,任要将他加入队列,这和hdu 4528很像.所以我们不能只单纯的标记每个点有没有走过,而是要标记走过该点的状态如何.如果上面的数据能过,那就基本上没问题了.下面为ac代码

#include<iostream>
#include<queue>
#include<cstring>
#define maxn 100+5
using namespace std;
int n,m;
int k,x1,y1,x2,y2;
char mapp[maxn][maxn];
int visit[maxn][maxn];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int flag;
struct stu
{
	int x,y,di,lim;
};
void bfs()
{
	stu x,y;
	queue<stu>root;
	x.x=x1;x.y=y1;x.di=-1;x.lim=-1;
	root.push(x);
	visit[x.x][x.y]=0;
	while(root.size())
	{
		x=root.front() ;
		root.pop();
		if(x.x==x2&&x.y==y2){flag=1;return;}
		for(int i=0;i<4;i++)
		{
			y.x=x.x+dir[i][0];
			y.y=x.y+dir[i][1];
			y.di=x.di;
			y.lim=x.lim;
			if(y.di!=i) y.di=i,y.lim++;
			if(y.x<0||y.x>=n||y.y<0||y.y>=m||visit[y.x][y.y]<y.lim||mapp[y.x][y.y]=='*'||y.lim>k) {continue;}
			root.push(y);
			//cout<<y.x<<y.y<<endl;
			visit[y.x][y.y]=y.lim; 
		}
	}
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i=0;i<n;i++) cin>>mapp[i];
		cin>>k>>y1>>x1>>y2>>x2;
		y1--;x1--;y2--;x2--;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<m;j++)
			{
				visit[i][j]=1<<20;
			} 
		}
		flag=0;
		bfs();
		if(flag) cout<<"yes"<<endl;
		else cout<<"no"<<endl;
	}
	return 0;
}


hdu 1728 逃离迷宫

标签:

原文地址:http://blog.csdn.net/zafkiel_nightmare/article/details/45068481

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!