[NOJ]僵尸双来了

这篇博客介绍了一种基于二维矩阵的僵尸路径规划问题,其中僵尸需要在天亮前抵达目标位置,途中会遇到地刺消耗生命值、坚果需要花费时间食用等障碍。通过广度优先搜索算法(BFS)来寻找最短路径,输出僵尸到达目标的最少时间,如果无法到达则输出-1。题目中给出了输入输出示例,并提供了实现算法的C++代码。
摘要由CSDN通过智能技术生成

[NOJ]僵尸双来了

描述

聪明的佳佳很善于布置花园,所以僵尸没能在天亮之前冲到佳佳家里,这次僵尸又又要来佳佳家做客了,佳佳跟爸爸逛超市时买了一个大坚果,把花园重新布置了一下,你拿到了花园的地图(以二维矩阵的形式表示)以及起点和佳佳家的位置。花园里某些位置有地刺,僵尸过的时候每次需要消耗一个单位的生命值,有些位置放了坚果,僵尸很懂礼貌,到达该位置后一定要吃完主人给准备的“小点心”后才会离开,当然吃掉它需要很长时间,僵尸有一定数量的生命值,看看又聪明又懂礼貌的僵尸能否在天亮前到达佳佳家里?能的话,最少花费多少时间。

输入

输入的第一行包含三个整数:m,n,b,t。代表m行n列的地图、僵尸的生命值b和吃掉坚果花费的时间t。m,n都是小于200的正整数,t是小于10的正整数,第2行开始的m行是m行n列的花园地图,其中!代表起点,+表示佳佳家。、代表通路,w代表地刺,W代表钢地刺(可怜的佳佳平时洗碗太少,关键的时候没钱买钢地刺),o表示坚果,#表示墙。

输出

输出僵尸到达佳佳家最少需要花费的时间。如果无法到达,则输出-1。

输入样例

4 4 2 3
#!##
、、##
ow#+
、w、、

输出样例

11

#include<iostream>
#include<queue>

using namespace std;
queue<int>qx,qy;

int m,n,t,b;
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int vis[21][21],life[21][21];
char map[21][21];

int bfs()
{
	int x,y;
	while(!qx.empty())
	{
		x=qx.front();
		y=qy.front();
		qx.pop();
		qy.pop();
		for(int k=0;k<4;k++)
		{
			int i,j;
			i=x+dir[k][0];
			j=y+dir[k][1];
			if(i>=0&&i<m&&j>=0&&j<n&&map[i][j]!='#')
			{
				if(map[i][j]=='+') return vis[x][y]+1;
				if(map[i][j]=='*'&&(life[x][y]>life[i][j]||!vis[i][j])){
					vis[i][j]=vis[x][y]+1;
					life[i][j]=life[x][y];
					qx.push(i);
					qy.push(j);
				}
				else if(map[i][j]=='w'&&life[x][y]>1&&(life[x][y]-1>life[i][j]||!vis[i][j])){
					vis[i][j]=vis[x][y]+1;
					life[i][j]=life[x][y]-1;
					qx.push(i);
					qy.push(j);
				}
				else if(map[i][j]=='o'&&(life[x][y]>life[i][j]||!vis[i][j])){
					vis[i][j]=vis[x][y]+t+1;
					life[i][j]=life[x][y];
					qx.push(i);
					qy.push(j);
					//cout<<i<<j<<endl;
				}
				//cout<<qx.front()<<' '<<qy.front()<<endl;
			}
		}
	}
	return 0;
}

int main()
{
	cin>>m>>n>>b>>t;
	int i,j;
	int x,y;
	for(i=0;i<m;i++){
		for(j=0;j<n;j++){
			cin>>map[i][j];
			if(map[i][j]=='!'){
				x=i;
				y=j;
			}
		}
	}
	qx.push(x);
	qy.push(y);
	vis[x][y]=1;
	life[x][y]=b;
	cout<<bfs()-1<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值