百练 鸣人和佐助(优先队列+BFS)

这也是一个迷宫题,通过这个题继续复习优先队列的使用

这个题的优先队列条件是在步数相同的情况下,优先走查克拉消耗小

题目链接

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

int m,n,t;
char mp[205][205];
int vis[205][205];
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
struct node//依然是优先队列的使用 
{
	int x;
	int y;
	int chakela;
	int step;
	node(int a,int b,int c,int d)
	{
		x = a;
		y = b;
		chakela = c;
		step = d;
	}
	node(){}
	bool operator < (const node &a) const //按照查克拉最小值优先 结构体优先队列 
	{
		if(a.step==step)
		{
			return a.chakela<chakela;//路径相同情况下 查克拉消耗小的优先 
		}
		else
			return a.step<step; 
	}
}s,tt,temp;
priority_queue <node> pq;
void bfs()
{
	pq.push(s);
	vis[s.x][s.y] = 1;
	while(pq.size())
	{
		temp = pq.top();
		pq.pop();
		if(temp.x==tt.x&&temp.y==tt.y)
		{
			printf("%d\n",temp.step);
			exit(0) ;
		} 
		for(int i=0;i<4;i++)
		{
			int nx = temp.x+dx[i];
			int ny = temp.y+dy[i];
			if(nx>=0&&nx<m&&ny>=0&&ny<n&&vis[nx][ny]==0)//消耗的查克拉需要能走到 
			{
				if(mp[nx][ny]=='#'&&temp.chakela+1<=t)
				{
					pq.push(node(nx,ny,temp.chakela+1,temp.step+1));
					vis[nx][ny] = 1;
				}
				if(mp[nx][ny]=='*'&&temp.chakela<=t)
				{
					pq.push(node(nx,ny,temp.chakela,temp.step+1));
					vis[nx][ny] = 1;
				}
				if(mp[nx][ny]=='+'&&temp.chakela<=t)
				{
					pq.push(node(nx,ny,temp.chakela,temp.step+1));
					vis[nx][ny] = 1;	
				} 	
			}  
		}
	}
	return ;
} 
int main(void)
{
	memset(vis,0,sizeof(vis));
	scanf("%d%d%d",&m,&n,&t);//m行n列 且一开始拥有的查克拉数量为t
	for(int i=0;i<m;i++)
	{
		scanf("%s",mp[i]);
	}
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<n;j++)
		{
			if(mp[i][j]=='@')
			{ 
				s = node(i,j,0,0);//找到一个起始点 
			}
			if(mp[i][j]=='+')
			{
				tt = node(i,j,t,0);//这里似乎只有ij是有用的 
			} 
		}
	}
	bfs();
	printf("-1\n");
} 

迷宫一般问题都不要忘记那个标记已经走过得数组

但是还差一个变种的迷宫题没有解决,即有钥匙可以重复走的迷宫,暂时还没有理解到方法...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值