POJ 3669 Meteor Shower BFS

Description
Bessie hears that an extraordinary meteor shower is coming; reports say that these meteors will crash into earth and destroy anything they hit. Anxious for her safety, she vows to find her way to a safe location (one that is never destroyed by a meteor) . She is currently grazing at the origin in the coordinate plane and wants to move to a new, safer location while avoiding being destroyed by meteors along her way.
The reports say that M meteors (1 ≤ M ≤ 50,000) will strike, with meteor i will striking point (Xi, Yi) (0 ≤ Xi ≤ 300; 0 ≤ Yi ≤ 300) at time Ti (0 ≤ Ti ≤ 1,000). Each meteor destroys the point that it strikes and also the four rectilinearly adjacent lattice points.
Bessie leaves the origin at time 0 and can travel in the first quadrant and parallel to the axes at the rate of one distance unit per second to any of the (often 4) adjacent rectilinear points that are not yet destroyed by a meteor. She cannot be located on a point at any time greater than or equal to the time it is destroyed).
Determine the minimum time it takes Bessie to get to a safe place.
Input

  • Line 1: A single integer: M
  • Lines 2…M+1: Line i+1 contains three space-separated integers: Xi, Yi, and Ti
    Output
    Line 1: The minimum time it takes Bessie to get to a safe place or -1 if it is impossible.
    Sample Input
    4
    0 0 2
    2 1 2
    1 1 2
    0 3 5
    Sample Output
    5

题目大意:
一共n个流星雨即将攻击地球,攻击到某个点时将会使该点及其上下左右四个点都被摧毁,当一个点被摧毁后,我们的女主Bessie就不能待在这个地方了。Bessie要在地球上找到一个地方让她能够度过灾难。把整个地图看作一张二维表,设该女孩在原点。其中输入第一行为流星个数n。接下来n行,每行3个值:x,y,t。代表着(x,y)这一点将在t时被流星攻击。输出Bessie逃命的最短时间,Bessie在每一个单位时间内可以向上下左右中的一个方向移动一个单位距离。如果逃离失败,那就输出-1.。

解题思路:
该题的难点在于地图是随着时间动态变化的。
使用二维数组map[][]来保存地球上的各个位置信息,map的值代表该点被摧毁的最近时间(一个点可能被多次摧毁,多次被直接命中或者被波及,我们需要保存最近的时间),初始值为INF,输入全部的流星信息后,地图上值仍为INF的点就是最后的安全地带
女主需要在一个点被摧毁之前到达该点:

if (now.t >= map[nx][ny]) continue;

题目中有最小字眼,考虑使用广度优先搜索

注意:

  • oj平台上的测试样例有超出范围的,我把数组开得更大了一些才AC。
  • 需要提前剪枝
  • 我使用cin输入时选择C++ AC成功,选择G++超时,后来改成scanf输入成功AC

AC代码

#include<iostream>
#include<queue>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define INF 0x3fffffff
struct node {
	int x, y;
	int t;
};
queue<node> q;
int map[320][320];//数组开得更大一些
bool mark[320][320];
int mynext[4][2] = { 1,0,-1,0,0,1,0,-1 };
int BFS(int x, int y) {
	while (!q.empty()) q.pop();
	node tmp;
	tmp.x = x; tmp.y = y; tmp.t = 0;
	q.push(tmp);
	while (!q.empty()) {
		tmp = q.front();
		q.pop();
		for (int i = 0; i < 4; i++) {
			int nx = tmp.x + mynext[i][0];
			int ny = tmp.y + mynext[i][1];
			if (nx < 0 || ny < 0 || nx>310 || ny>310) continue;
			if (tmp.t + 1 >= map[nx][ny]) continue;//在该点被摧毁之前到达
			if (mark[nx][ny] == true) continue;
			node now;
			now.x = nx; now.y = ny; now.t = tmp.t + 1;
			q.push(now);
			mark[nx][ny] = true;
			if (map[nx][ny] == INF) { return now.t; }//到达安全地带
		}
	}
	return -1;
}
int main() {
	for (int i = 0; i <= 310; i++) {
		for (int j = 0; j <= 310; j++) {
			map[i][j] = INF;
			mark[i][j] = false;
		}
	}
	int n;
	scanf("%d", &n);
	//cin >> n;//G++超时
	while (n--) {
		int x, y, tmp;
		scanf("%d%d%d", &x, &y, &tmp);
		//cin >> x >> y;
		//cin >> tmp;
		map[x][y] = min(map[x][y], tmp);//自身也应该取最小值!!!
		//更新是使用新的值  也就是用中心被摧毁的时间去尝试更新周围4个点的值
		//因为如果原map[x][y]小于tmp,但map[x][y]可能是被其他流星波及的值,此时无法波及周围的点
		for (int i = 0; i < 4; i++) {
			int nx = x + mynext[i][0];
			int ny = y + mynext[i][1];
			if (nx < 0 || ny < 0 || nx>310 || ny>310) continue;
			map[nx][ny] = min(map[nx][ny], tmp);
		}
	}
	mark[0][0] = true;
	cout << BFS(0, 0) << endl;
	//system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值