北大ACM3669——Meteor Shower~~简单的广搜

这一题,简单的广搜的应用,只是题目的陷进比较多。

题目大概的意思是,一个人在Point(0,0)的位置,然后会有陨石坠落,陨石坠落的地方的上下左右中都会被砸毁,每一个陨石会在第T秒坠落。问你找到一个安全的地方的最短时间,否则输出-1.

下面是AC的代码,有详细的注释:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int MAX = 50005;    //陨石最大数量

class data
{
public:
	int x, y, Time;
};
data s[MAX];              //陨石坠落的位置和时间
int map[305][305], M;     //map表示point(i, j)位置运算坠落的最早时间。
bool safe[305][305], vis[305][305];   //safe是安全的地方,则为true
int xy[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1};//四个方位

int bfs()
{
	queue<data>que;
	data temp, te;
	temp.x = temp.y = temp.Time = 0;   //开始位置0,0和时间为0;
	que.push(temp);
	vis[0][0] = true;                  //标记已经返问过
	while(!que.empty())
	{
		te = que.front();
		que.pop();
		for(int i = 0; i < 4; i++)      //四个方位进行搜索
		{
			int x = te.x + xy[i][0];
			int y = te.y + xy[i][1];
			int time = te.Time + 1;
			if(x >= 0 && y >= 0 && map[x][y] > time && !vis[x][y]) //没返问过的,陨石还没落下的位置可以走
			{
				if(safe[x][y])        //如果找到安全地方,返回时间。
					return time;
				vis[x][y] = true;     //标记已经返问过
				temp.x = x;
				temp.y = y;
				temp.Time = time;
				que.push(temp);       //入队
			}
		}
	}
	return -1;                        //不能找到安全地方
}

int main()
{
//	freopen("data.txt", "r", stdin);  //这里忘记注释掉了,wr了一次,坑
	int i, j, k;
	while(scanf("%d", &M) != EOF)
	{
		memset(safe, true, sizeof(safe));  //初始化safe
		memset(vis, false, sizeof(vis));	//初始化vis
		for(i = 0; i < 305; i++)          //初始化map
			for(j = 0; j < 305; j++)
				map[i][j] = 10000000;
		for(i = 0; i < M; i++)
		{
			scanf("%d%d%d", &s[i].x, &s[i].y, &s[i].Time);
			safe[s[i].x][s[i].y] = safe[s[i].x - 1][s[i].y] = safe[s[i].x][s[i].y - 1] =
				safe[s[i].x + 1][s[i].y] = safe[s[i].x][s[i].y + 1] = false;     //标记陨石会砸到的地方
		}
		data temp;
		for(j = 0; j < M; j++)                 //更新map中每一个位置陨石最早掉落的时间,注意,是最早的时间。
		{                                      //刚开始忘记考虑这一点了。坠落的时间不是降序
			temp = s[j];
			if(map[temp.x][temp.y] > temp.Time)
				map[temp.x][temp.y] = temp.Time;
			for(k = 0; k < 4; k++)
			{
				int x = temp.x + xy[k][0];
				int y = temp.y + xy[k][1];
				if(x >= 0 && y >= 0 && map[x][y] > temp.Time)
					map[x][y] = temp.Time;
			}
		}
		if(map[0][0] == 0)                      //开始时,陨石就砸下来了,就直接死掉了,-1;
			printf("-1\n");
		else
			printf("%d\n", bfs());
	}
	return 0;
}
时间: 2024-10-12 02:03:43

北大ACM3669——Meteor Shower~~简单的广搜的相关文章

HDU 1253 (简单三维广搜) 胜利大逃亡

奇葩!这么简单的广搜居然爆内存了,而且一直爆,一直爆,Orz 而且我也优化过了的啊,尼玛还是一直爆! 先把代码贴上睡觉去了,明天再来弄 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <cmath> 7 using namespace std; 8 9 struct Poin

HDU 1240 (简单三维广搜) Asteroids!

给出一个三维的迷宫以及起点和终点,求能否到大终点,若果能输出最短步数 三维的问题无非就是变成了6个搜索方向 最后强调一下xyz的顺序,从输入数据来看,读入的顺序是map[z][x][y] 总之,这是很基础的一道题 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <algorithm

poj 3278:Catch That Cow(简单一维广搜)

Catch That Cow Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 45648   Accepted: 14310 Description Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,00

poj 2251 Dungeon Master(简单三维广搜)

题意: 之前做过的所有题都是   在一个平面   上搜索 . 本题很新,在一个三维空间里 ,首先   l  x  y   分别代表 l 层   每一层有 x 行   y 列 问从 S 开始   走到 E   最小步是多少    显然用广搜,只是多了一个向上向下的搜索. 注意: 所谓广搜  ,是一层一层的搜,  每一层其步数是一样的   ,可以通过建立一个数组存步数 ,也可以 将步数同时存入队列中 另外搜过的要做标记, 在做标记时  尽量要在里面做标记(就是每搜过一个点就  立马 将之标记)不然一

POJ 3669 Meteor shower 简单BFS, 有坑点

Meteor Shower 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

杭电1175——连连看~简单的广搜

这一题,做了好久,终于AC了,感觉题目有点坑,唉,题目不是很难,就是坑!!-- 找一个错误,找了半天,后来才看到是变量用错了!!~ 题目中的b数组是标记数组. #include <iostream> #include <cstdio> #include <queue> using namespace std; #define INF 1000000 int xy[4][2] = { { -1 , 0 } , { 1 , 0 } , { 0 , -1 } , { 0 ,

HDU 2267 How Many People Can Survive(广搜,简单)

题目 //一道简单的广搜水题 #include<queue> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; struct tt { int x,y; }; char mp[310][310]; int vis[310][310]; //看了题解,发现只有4个方向,而不是8个方向....题目貌似都没说清楚

poj 3984:迷宫问题(广搜,入门题)

迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7635   Accepted: 4474 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要

杭电ACM1312——Red and Black~~广搜

这一题,简单的广搜或者深搜都可以搞定,时间复杂度都差不多. 我用的是广搜.题目的意思是:@是一个人的起始位置,#不可以走,. 可以走,求出可以走的位置的个数. 一开始没有用结构体来存储坐标,直接用的是z = x * 10 + y:将z入队,结果错了,原因是在取余整除的时候会出错.改用结构体就OK了. 下面是AC的代码: #include <iostream> #include <queue> #include <cstdio> using namespace std;