HDU 1242 (BFS+优先队列)

初次使用优先队列;

有的人用普通队列也能过,但是,我只能说,那是数据太水了;

普通队列能过的将类似下面两句改改顺序:

int xx[4] = {1,-1,0,0};

int yy[4] = {0,0,1,-1};

也许就过不了了;

因为如果用普通方法,最后得到的是最优步数,而不是最优时间;

来自Jason的解释:

普通队列+bfs确实是蒙对的,因为击败守卫需要消耗时间1,因此普通队列每一次出队列的元素只是步数上最优,但不一定是时间上最优的,这时即使我们把整个迷宫搜完以最小值作为最优依然不行,因为每一步处理完成都会把该状态标记为已处理vis[i][j]=1,因此,只要有一步不是最优,就会影响后面的结果。这题的正确做法是优先队列,每一次出队都是出时间最少的,这样可以保证每一步最优,并且一旦搜到目标即可立刻结束。

#include <iostream>
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
char map[205][205];
int xx[4] = {1,-1,0,0};
int yy[4] = {0,0,1,-1}; 
bool visit[205][205];
int n,m;
struct point
{
	int x;
	int y;
	int step;
	friend bool operator < (point a, point b)
	{
		return a.step > b.step;
	}
}a,b;

int bfs()
{
	int flag = 0;
	memset(visit,false,sizeof(visit));
	visit[a.x][a.y] = true;
	priority_queue<point> q;
	q.push(a);
	while(!q.empty())
	{
		
		b = q.top();
		q.pop();
		if(map[b.x][b.y] == 'r')
		{
			flag = b.step;
			break;
		}	
		for(int i = 0; i < 4; i++)
		{
			a.x = b.x + xx[i];
			a.y = b.y + yy[i];
			a.step = b.step + 1;
			if(!visit[a.x][a.y]&&map[a.x][a.y]!='#')
			{
				visit[a.x][a.y] = true;
				if(map[a.x][a.y]=='x')
					a.step = a.step + 1;
				q.push(a);
			}
		}
	}
	return flag;
}
int main()
{
	while(cin>>n>>m)
	{
		for(int i=0;i<=n+1;++i)
            map[i][0]=map[i][m+1]='#';
        for(int i=0;i<=m+1;++i)
            map[0][i]=map[n+1][i]='#';
		for(int i = 1; i <= n; i++)
		{
			for(int j = 1; j <= m; j++)
			{
				cin>>map[i][j];
				if(map[i][j]=='a')
				{
					a.x = i;
					a.y = j;
					a.step = 0;
				}
			}
		}
		int step = bfs();
		if(step)
		{
			cout<<step<<endl;;
		}	
		else
		{
			cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;;
		}
	}
	return 0;
	
}
/*
7 8
#.#####.
#.a#..r.
#..#x...
..#..#.#
#...##..
.#......
........
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值