BFS 洛谷 Meteor Shower S

题目

题目链接

代码

先简单写一下吧,这道题目说多了都是泪
细节太多了

/*
本题又包含了一个时间上的维度,因此需要在判定的时候多加一个判定条件
 
首先不看时间,求出哪些点是永远安全的,如果bfs的时候正好到了这个点
那么就可以直接输出了
 
*/

#include<iostream>
#include<queue>

using namespace std;

const int N=500;//只是说陨石会砸在一片(300,300)的区域,没说农场多大,因此这里开大一点 

int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};

typedef pair<int,int> PII;
queue <PII> q;
int M;
int yun[60000][2];//记录陨石掉落的位置 
int g[N][N];//0表示不会被影响到 
int step[N][N];//到达的步数
int t[N][N];//到达各坐标的时间 
int go[N][N];//记录走过没有 

int ch(int x){
	if(x==0)
		return 99999;
	else
		return x;
}

int bfs(){
	q.push({0,0});//从第一个开始
	go[0][0]=1;//标记走过 
	while(q.size()!=0){
		auto m=q.front();
		q.pop();
		if(g[m.first][m.second]==0){//如果这个点永远没有危险 
			return step[m.first][m.second];
		}
		//如果有危险(但是要根据时间判断)
		for(int i=0;i<4;i++){
			int xx=m.first+dx[i],yy=m.second+dy[i];
			if(xx>=0&&yy>=0&&go[xx][yy]==0&&step[m.first][m.second]+1<ch(t[xx][yy])){//能走,且没走过,并且在陨石到来之前 
				q.push({xx,yy});
				step[xx][yy]=step[m.first][m.second]+1;
				go[xx][yy]=1;
			}
		}
	} 
	return -1;
}


int main(){
	cin>>M;
	int x;
	int set[N][N];
	//初始化各个点要注意,每个点应该算它最早开始降落的陨石时间
	//并且不是他周围的要最早,它本身也要更新啊!!!我就被这个坑死了
	//细节自己以后琢磨,说多了都是泪啊 
	for(int i=1;i<=M;i++){
		cin>>yun[i][0]>>yun[i][1];
		g[yun[i][0]][yun[i][1]]=1;
		cin>>x;
		if(set[yun[i][0]][yun[i][1]]==0||t[yun[i][0]][yun[i][1]]>=x){
			set[yun[i][0]][yun[i][1]]=1;
			t[yun[i][0]][yun[i][1]]=x;
		}
		for(int j=0;j<4;j++){
			int xx=yun[i][0]+dx[j],yy=yun[i][1]+dy[j];
			if(xx>=0&&yy>=0)	
				g[xx][yy]=1;
				if(ch(t[xx][yy])>=x){
					t[xx][yy]=x;
					set[xx][yy]=1;
				}
					
		}//标记那些最终会被影响到的地方,这样的话,那些0的地方就永远安全了 
	}
	int ans;
	ans=bfs();
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值