其他分享
首页 > 其他分享> > 「USACO08FEB」Meteor Shower S 题解 (BFS)

「USACO08FEB」Meteor Shower S 题解 (BFS)

作者:互联网

题目连接


Fir.坑点介绍大会


坑空间

坐标不能小于0,but 可以超过300

坑时间

1.流星砸下时间要最早的为准

2.流星砸下来的时间可以为0!


出题人:祝您过了样例,听取WA声一片


Sec.记录流星下砸时间


对此,我们可以定义\(a_{i,j}\)表示第\(i,j\)个点的遭殃时间。

初始化时请注意:

| 根据预报,一共有 $M $颗流星 \((1\leq M\leq50,000)\) 会坠落在农场上,其中第i颗流星会在时刻$ T_i(0\leq T_i\leq1,000)$ 砸在坐标为
$ X_i, Y_i(0\leq X_i\leq 300,0\leq Y_i\leq300) $ 的格子里。

\(T\)可以等于0

所以强烈推荐使用 memset

#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f//宏定义

using namespace std;

int X[]={0,0,1,-1},Y[]={1,-1,0,0};//预处理技巧

int n;
int a[502][502];
bool v[502][502];

inline int mymin(int a,int b){
	if(a<b)return a;
	return b;
}

inline void ass(int x,int y,int l){
	a[x][y]=mymin(l,a[x][y]);
	for(int i=0;i<4;i++){
		int tx=x+X[i];
		int ty=y+Y[i];
		if(tx<0||ty<0)continue;
		a[tx][ty]=mymin(l,a[tx][ty]);
	}
}

int main(){
	memset(a,INF,sizeof(a));//memset专场
    
	scanf("%d",&n);
	int x,y,l;
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&x,&y,&l);
		ass(x,y,l);
	}
	return 0;
}

现在\(a\)数组里就是每块土地遭殃的时间了。


Thi.BFS写作计划

接下来,就是模板\(BFS\)

\(BFS\)模板写法:

while(/*队列不为空*/){
	//调用队头元素;
	//删除队头;
   for(/*预处理-四向搜索或八向搜索*/){
		//搜索新坐标
		//判断是否合法
		//存入队尾
   }
}

在这里我看见很多大佬都在用\(STL\)中的\(queue\),其实我觉得用一个结构体数组就够了

struct FE{
	int x,y,t;//x,y记录坐标,t记录时间
}q[10000001];

int t,h;//h为队头,t为队尾

inline int bfs(){
	t++;
	int x,y,l;
	
	while(h<t){
		x=q[h].x,y=q[h].y,l=q[h].t+1;
		h++;
		if(a[x][y]==0x3f3f3f3f){
			return l;
		}
		for(int i=0;i<4;i++){
			int tx=x+X[i];
			int ty=y+Y[i];
			if(tx<0||ty<0)continue;
			if(v[tx][ty]==true)continue;
			v[tx][ty]=true;
			if(a[tx][ty]>l){
				q[t].x=tx,q[t].y=ty,q[t].t=l;
				t++;
			}
		}
	}
	return 0;
}

把以上代码连起来,你就能AC了:

#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x3f3f3f3f

using namespace std;

struct FE{
	int x,y,t;
}q[10000001];

int t,h;
int X[]={0,0,1,-1},Y[]={1,-1,0,0};

int n;
int a[502][502];
bool v[502][502];

inline int mymin(int a,int b){
	if(a<b)return a;
	return b;
}

inline void ass(int x,int y,int l){
	a[x][y]=mymin(l,a[x][y]);
	for(int i=0;i<4;i++){
		int tx=x+X[i];
		int ty=y+Y[i];
		if(tx<0||ty<0)continue;
		a[tx][ty]=mymin(l,a[tx][ty]);
	}
}

inline int bfs(){
	t++;
	int x,y,l;
	
	while(h<t){
		x=q[h].x,y=q[h].y,l=q[h].t+1;
		h++;
		if(a[x][y]==0x3f3f3f3f){
			return l;
		}
		for(int i=0;i<4;i++){
			int tx=x+X[i];
			int ty=y+Y[i];
			if(tx<0||ty<0)continue;
			if(v[tx][ty]==true)continue;
			v[tx][ty]=true;
			if(a[tx][ty]>l){
				q[t].x=tx,q[t].y=ty,q[t].t=l;
				t++;
			}
		}
	}
	return 0;
}

int main(){
	memset(a,INF,sizeof(a));
	scanf("%d",&n);
	int x,y,l;
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&x,&y,&l);
		ass(x,y,l);
	}
	printf("%d",bfs()-1);
	return 0;
}

$$-----END-----$$

标签:BFS,int,题解,Shower,leq,USACO08FEB,include,502,流星
来源: https://www.cnblogs.com/wintersunny/p/15365694.html