题目 英雄 (BFS)

英雄(hero.cpp/pas)


题目描述(Description):

城堡迷宫由N× M个格子组成,英雄Mario玛丽奥要在城堡迷宫中从起始点移动
点去拯救被怪物掳去的公主,他每一步只能从当前所在的格子移动到相邻的4个格子
而且不能移出城堡的范围,走一步需要1秒的时间。
城堡中某些格子里面有弹簧,每个弹簧具有特定的能量K,不同弹簧的K值不一
。如果Mario跳到一个有弹簧的格子,他就会继续向前跳K个格子或者被墙所阻挡无
向前,这个时间忽略不计。


请你计算Mario从起始点到达目标点(公主位置)需要的最短时间,如果不能到
出“ Impossible”。


输入文件(hero.in):
第一行,两个整数, NM3<=N,M<=100),分别表示城堡的行和列。
第二行,一个非负整数K,表示弹簧的数量。接下来K行,每行含3个正整数—
XYP。其中XY是弹簧的坐标( 2<=X<=N-12<=Y<=M-1 ), P是该弹簧的能
接下来最后两行,第一行是Mario的坐标,第二行是公主的坐标。
注意:输入文件保证没有一个弹簧是挨着城堡围墙的。

输出文件(hero.out):
输出Mario从初始位置到达公主所在位置需要的最短时间(秒)。
如果不能到达,则输出“ Impossible”。(引号不需输出)

样例(Sample):
Sample Input Case 1:
10 10
12
7 5
2 8
1 1
Sample Output Case 1:
3



/

思路:

裸BFS 还犹豫什么!!!

只是要注意,Mario可以从一个弹簧跳到另一个弹簧。

还有 无解的情况只可能是几个弹簧把公主(目标)包围住了,有意的话可以特判一下优化时间,数据范围就那一点儿,我就没做。

好叻,上代码。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<queue>
using namespace std;

int n,m,k;
int ex,ey;
int map[100+10][100+10];
int hash[100+10][100+10];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};

struct code
{
	int x,y;
	int step;
}start;
queue<code> q;

void read()
{
	cin>>n>>m>>k;
	int x,y,p;
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d%d",&x,&y,&p);
		map[x][y]=p;
	}
	scanf("%d%d",&x,&y);
	start.x=x; 
	start.y=y;
	start.step=0;
	hash[x][y]=1;
	q.push(start);
	scanf("%d%d",&ex,&ey);
}

code expend(code u,int i)
{
	u.x+=dx[i];
	u.y+=dy[i];
	u.step++;
	while(map[u.x][u.y]>0)
	{
		int p=map[u.x][u.y];
		if(dx[i]==1) u.x+=p;
		else if(dx[i]==-1) u.x-=p;
		else if(dy[i]==1) u.y+=p;
		else if(dy[i]==-1) u.y-=p;
		
		if(u.x>n) u.x=n;
		else if(u.x<1) u.x=1;
		else if(u.y>m) u.y=m;
		else if(u.y<1) u.y=1;
	}
	return u;
}

bool check(code v)
{
	if(v.x<1||v.x>n||v.y<1||v.y>m) return false;
	if(hash[v.x][v.y]) return false;
	if(v.x==ex&&v.y==ey)
	{
		printf("%d\n",v.step);
		exit(0);
	}
	return hash[v.x][v.y]=true;
}

void work()
{
	while(!q.empty())
	{
		code u=q.front();q.pop();
		for(int i=0;i<4;i++)
		{
			code v=expend(u,i);
			if(check(v))
			{
				q.push(v);
			}
		}
	}
	printf("Impossible\n");
}

int main()
{
	read();
	work();
	return 0;
}

/







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值