[USACO08FEB]Meteor Shower S

原题链接

题解

我们用 \(a[i][j]\) 表示坐标 \((i,j)\) 最先在哪一时刻被撞击,分两种情况:

  1. 如果没有陨石撞击,我们将其赋上极值1001,因为 \(0 \le T_i \le 1000\)
  2. 如果有陨石撞击,因为可能会有多次,我们取最小的时间。

所以,初始化坐标系代码如下:

for(int i=0;i<=310;i++)
for(int j=0;j<=310;j++)
	a[i][j]=1001;
for(int i=1,x,y,t;i<=n;i++)
{
	read(x);read(y);read(t);
	a[x][y]=min(a[x][y],t);
	for(int j=0;j<=3;j++)
	{
		int tx=x+dx[j],ty=y+dy[j];
		if(tx>=0&&ty>=0)a[tx][ty]=min(a[tx][ty],t);
	}
}

最后从 \((0,0)\) 开始 BFS。

Code:

#include<bits/stdc++.h>
using namespace std;
void read(int &x)
{
	char ch=getchar();
	int r=0,w=1;
	while(!isdigit(ch))w=ch=='-'?-1:1,ch=getchar();
	while(isdigit(ch))r=(r<<3)+(r<<1)+(ch^48),ch=getchar();
	x=r*w;
}
int a[350][350],f[350][350];
struct kkk
{
	int x,y,step;
};
queue<kkk>q;
int dx[]={0,-1,0,1};
int dy[]={-1,0,1,0};
void bfs()
{
	f[0][0]=1;
	q.push(kkk{0,0,0});
	while(!q.empty())
	{
		kkk t=q.front();
		q.pop();
		if(a[t.x][t.y]==1001)
		{
			printf("%d",t.step);
			return;
		}
		for(int i=0;i<=3;i++)
		{
			int tx=t.x+dx[i],ty=t.y+dy[i];
			if(tx>=0&&tx<=310&&ty>=0&&ty<=310&&!f[tx][ty]&&t.step+1<a[tx][ty])
				q.push(kkk{tx,ty,t.step+1}),f[tx][ty]=t.step+1;
		}
	}
	printf("-1");
}
int main()
{
	int n;
	read(n);
	for(int i=0;i<=310;i++)
	for(int j=0;j<=310;j++)
		a[i][j]=1001;
	for(int i=1,x,y,t;i<=n;i++)
	{
		read(x);read(y);read(t);
		a[x][y]=min(a[x][y],t);
		for(int j=0;j<=3;j++)
		{
			int tx=x+dx[j],ty=y+dy[j];
			if(tx>=0&&ty>=0)a[tx][ty]=min(a[tx][ty],t);
		}
	}
	bfs();
	return 0;
}
posted @ 2022-07-06 11:39  Epoch_L  阅读(16)  评论(0编辑  收藏  举报