POJ NO.3669 Meteor Shower(经典BPS,,,)

本文介绍如何使用BFS算法解决给定时间内流星降落路径的优化问题,通过标记时间和路径,实现高效的路径查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述:

给你一个整数M表示流行的个数,然后给你M组数据每组包含3个整数,分别表示坐标和降落的时间。

题目链接:点击打开链接

思路:

先把时间都标记好,在跑一遍BFS即可。

注意:走过的点不能再走!!!还要注意时间,这种解法很费时所以将输入输出流换成了scanf,,,,,

代码:

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

using namespace std;

struct P
{
    int x, y, z;
};

const int MAX = 302;
int field[MAX][MAX], foot[MAX][MAX];//foot用来判断是否该点是否走过
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};

int BFS();

int main()
{
    int t, arr[MAX][MAX];
    while(~scanf("%d", &t))
    {
        //把所有点都给赋值为INF
        for(int i = 0; i < 302; i++)
            for(int j = 0; j < 302; j++) field[i][j] = INF;
        //给数组foot全部赋值为0,表示所有的点都没走过
        memset(foot, 0, sizeof(foot));
        //给所有的点标记上时间(有流星来的时间)
        while(t--)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            if(field[x][y] > z)
                field[x][y] = z;
            for(int i = 0; i < 4; i++)
            {
                int nx = x + dx[i], ny = y + dy[i];
                if(nx >= 0 && nx <= 302 && ny >= 0 &&
                        ny <= 302 && field[nx][ny] > z)
                    field[nx][ny] = z;
            }
        }
        //跑一遍BFS即可
        int res = BFS();
        cout << res << endl;
    }
}

int BFS()
{
    queue<P> que;
    que.push((P)
    {
        0, 0, 0
    });
    while(que.size())//直到队列长度为0
    {
        P p = que.front();
        que.pop();
        if(field[p.x][p.y] == INF) return p.z;
        if(foot[p.x][p.y]) continue;//走过不能再走了(排除走过的点重新走的可能)
        foot[p.x][p.y] = 1;//标记该点已经走过
        for(int i = 0; i < 4; i++)
        {
            P n;
            n.x = p.x + dx[i];
            n.y = p.y + dy[i];
            n.z = p.z + 1;
            if(0 <= n.x && n.x < 302 && 0 <= n.y && n.y < 302 &&
                    n.z < field[n.x][n.y] && foot[n.x][n.y] == 0)
            {
                que.push(n);
            }
        }
    }
    return -1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值