[USACO08FEB] Meteor Shower S C++

[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;
}
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值