[USACO08FEB] Meteor Shower S
题目链接
提示
这道题虽然是普通的BFS练习题,但是细节比较多,有些地方需要注意。
- 暴力遍历处理流星的位置会超时,所以需要记录最早的时间。
- 题目并没有说不能超过300,所以是可以走出300的。
- 流星可能砸到同一块地上,我们需要记录的是最早的,防止判断时出问题。
- 无法到达需要返回-1。
过程
变量定义如下:
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii;
const int maxn = 3e2 + 10;
int m;
int mete[maxn][maxn]; // 记录流星落下的情况
bool vis[maxn][maxn]; // 遍历时需要的
const pii step[4] = { {1,0}, {0,1}, {-1,0}, {0,-1} };
struct Pos
{
int x, y, t;
Pos() { x = y = t = -1; }
Pos(int xx, int yy, int tt)
{
x = xx, y = yy, t = tt;
}
}; // 记录当前的位置与时间
首先处理输入输出
int main()
{
scanf("%d",&m);
memset(mete, 0x3f, sizeof(mete)); // 初始化成一个题目不能达到的大数
memset(vis, false, sizeof(vis));
for(int i = 0; i < m; i++)
{
int x, y, t;
scanf("%d%d%d",&x,&y,&t);
mete[x][y] = min(mete[x][y], t); // 因为可能重复,所以只取最早的
mete[x + 1][y] = min(mete[x + 1][y], t);
mete[x][y + 1] = min(mete[x][y + 1], t);
if(x - 1 >= 0)
mete[x - 1][y] = min(mete[x - 1][y], t);
if(y - 1 >= 0)
mete[x][y - 1] = min(mete[x][y - 1], t);
}
printf("%d\n",BFS());
return 0;
}
这里插一句话,有的人可能不知道:
memset函数是将输入的数字逐字节地进行拷贝,比如int型的数是4个字节,将其中的每个字节都变成 0x3f
,这就意味着其中的每一个int型都变成了 0x3f3f3f3f
。
接下来是BFS主体
int BFS() // 常规的BFS套路
{
queue<Pos> q;
q.push(Pos(0,0,0));
vis[0][0] = true;
while(!q.empty())
{
Pos now = q.front();
q.pop();
if(mete[now.x][now.y] == 0x3f3f3f3f)
return now.t; // 第一次找到的一定就是耗时最短的
for(int i = 0; i < 4; i++)
{
int a = now.x + step[i].first;
int b = now.y + step[i].second;
// 注意判断逻辑
if(a < 0 || b < 0 || mete[a][b] <= now.t+1 || vis[a][b])
continue;
vis[a][b] = true;
q.push(Pos(a,b,now.t+1));
}
}
return -1; //如果走不出来返回-1
}
完整代码
完整代码在这里,祝各位好运。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii;
const int maxn = 3e2 + 10;
int m;
int mete[maxn][maxn];
bool vis[maxn][maxn];
const pii step[4] = { {1,0}, {0,1}, {-1,0}, {0,-1} };
struct Pos
{
int x, y, t;
Pos() { x = y = t = -1; }
Pos(int xx, int yy, int tt)
{
x = xx, y = yy, t = tt;
}
};
int BFS()
{
queue<Pos> q;
q.push(Pos(0,0,0));
vis[0][0] = true;
while(!q.empty())
{
Pos now = q.front();
q.pop();
if(mete[now.x][now.y] == 0x3f3f3f3f)
return now.t;
for(int i = 0; i < 4; i++)
{
int a = now.x + step[i].first;
int b = now.y + step[i].second;
if(a < 0 || b < 0 || mete[a][b] <= now.t+1 || vis[a][b])
continue;
vis[a][b] = true;
q.push(Pos(a,b,now.t+1));
}
}
return -1;
}
int main()
{
scanf("%d",&m);
memset(mete, 0x3f, sizeof(mete));
memset(vis, false, sizeof(vis));
for(int i = 0; i < m; i++)
{
int x, y, t;
scanf("%d%d%d",&x,&y,&t);
mete[x][y] = min(mete[x][y], t);
mete[x + 1][y] = min(mete[x + 1][y], t);
mete[x][y + 1] = min(mete[x][y + 1], t);
if(x - 1 >= 0)
mete[x - 1][y] = min(mete[x - 1][y], t);
if(y - 1 >= 0)
mete[x][y - 1] = min(mete[x][y - 1], t);
}
printf("%d\n",BFS());
return 0;
}