【DG特长生2020】流星雨

这篇博客介绍了一种使用广度优先搜索(BFS)算法来解决天灾背景下难民避难时间最短的问题。文章通过设定流星降落坐标、时间及安全区域,运用BFS策略寻找从初始位置到安全区域的最短路径。代码实现中,当遇到流星撞击的位置,会跳过并继续搜索,直到找到安全区域或确定无法避免灾难。若能到达安全地点,则输出所需时间,否则输出-1。
摘要由CSDN通过智能技术生成

(自改题目背景)

“天灾降临,我们并非无计可施。”

天灾降临。

天灾信使朝坐标 ( 0 , 0 ) (0,0) (0,0) 的移动城市切尔诺伯格发送紧急情报:
一共有 M M M 颗流星将降落到该块区域,其落点坐标为 ( X i , Y i ) (Xi,Yi) (Xi,Yi),会在第 T i Ti Ti 个时间点落至地面。流星的力量会将它所在的位置,以及周围4个相邻的位置都化为焦土。生物无法再在这些位置上行走/生存。请尽快移入安全区域。(乌萨斯刁民,别看流星雨啦!!)

难民从第 0 0 0 个时间点开始移动,每次花费 1 s 1s 1s 向周围四格移动。如果一个位置在时刻 t t t 被流星撞击或烧焦,那么难民只能在 t t t 之前的时刻在这个位置出现。

求最少的避难时间,若无法避免,请回复 − 1 -1 1 。默哀。

该次天灾相关数据评估:
估测流星总数:
1 < = M < = 50 , 000 1 <= M <= 50,000 1<=M<=50,000
估测落地横坐标范围:
0 < = X i < = 300 0<=Xi<=300 0<=Xi<=300
估测落地纵坐标范围:
0 < = Y i < = 300 0<=Yi<=300 0<=Yi<=300
估测出现时间:
0 < = T i < = 1 , 000 0 <= Ti <= 1,000 0<=Ti<=1,000


BFS。


代码

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int last[501][501], timee[501][501], m, n, top = 1, xx, yy, tt;
int fx[6] = {0, -1, +1}, fy[6] = {0,0,0,-1,+1}; 
struct asdf{
	int x, y, t;
} startt;
queue<asdf> Q;
int main(){
	freopen("meteor.in","r",stdin);
	freopen("meteor.out","w",stdout);
	scanf("%d", &n);
	memset(last,0x7f,sizeof(last));
	for(int i = 1; i <= n; ++i){
		scanf("%d%d%d", &xx, &yy, &tt);
		last[xx][yy] = min(last[xx][yy], tt); //这些位置被流星最先破坏的时间
		last[xx+1][yy] = min(tt,last[xx+1][yy]);
		last[xx][yy+1] = min(tt,last[xx][yy+1]);
		if(xx > 0) last[xx-1][yy] = min(tt,last[xx-1][yy]);
		if(yy > 0) last[xx][yy-1] = min(tt,last[xx][yy-1]);
	}
	startt = (asdf){0, 0, 0};
	timee[0][0] = 0;
	if(last[0][0] == last[400][400]){  //如果原先的位置就是安全的
		printf("0");
		fclose(stdin);
		fclose(stdout);
		return 0;
	}
	Q.push(startt);
	while(!Q.empty()){
		asdf d = Q.front();
		Q.pop();
		if(last[d.x][d.y] <= d.t) continue;  //被炸
		for(int i = 1; i <= 4; ++i){
			int mbx = d.x + fx[i];  //目标位置
			int mby = d.y + fy[i];
			if(mbx >= 0 && mby >= 0) //目标位置在地图内
			if(last[mbx][mby] > d.t+1 && timee[mbx][mby] == 0){ //目标位置安全
				timee[mbx][mby] = timee[d.x][d.y] + 1; //处理时间
				if(last[mbx][mby] == last[400][400]) {  //到达安全地点
					printf("%d", timee[mbx][mby]);
					return 0;
				}
				Q.push((asdf){mbx, mby, timee[mbx][mby]});
			}
		}
	}
	printf("-1");
	fclose(stdin);
	fclose(stdout);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值