P2895 Meteor Shower S

点击查看代码
#include<bits/stdc++.h>
using namespace std;

const int MAXN = 400; 
const int INF = 1e9; //代表绝对安全
//存储被流星砸中的最早时间
int grid[MAXN][MAXN]; 
//既存储步数又起到vis数组的作用
int dist[MAXN][MAXN];

// 方向数组
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

struct Point {
    int x, y;
};

int bfs() {
    //做一个特判,如果起点在一开始就被砸了直接返回-1
    if (grid[0][0] == 0) return -1;

    //初始化与启动
    queue<Point> q;
    memset(dist, -1, sizeof(dist));
    q.push({0, 0});
    dist[0][0] = 0;

    while (!q.empty()) {
        //取出队头
        Point u = q.front();
        q.pop();

        // 终点判断,如果当前脚下的是永久安全区,那就直接返回
        if (grid[u.x][u.y] == INF) {
            return dist[u.x][u.y];
        }

        //观察邻居
        for (int i = 0; i < 4; i++) {
            int nx = u.x + dx[i];
            int ny = u.y + dy[i];

            // 下一步的时刻
            int next_time = dist[u.x][u.y] + 1;

            //判断与选择,不越界,没去过,安全性
            if (nx >= 0 && nx < MAXN && ny >= 0 && ny < MAXN && 
                dist[nx][ny] == -1 && 
                next_time < grid[nx][ny]) { // 核心:比流星快一步
                
                dist[nx][ny] = next_time;
                q.push({nx, ny});
            }
        }
    }

    //结束
    return -1;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    //初始地图为绝对安全
    for (int i = 0; i < MAXN; i++) {
        for (int j = 0; j < MAXN; j++) {
            grid[i][j] = INF;
        }
    }

    int m;
    cin >> m;
    while (m--) {
        int x, y, t;
        cin >> x >> y >> t;

        // 标记中心点,取最小值
        grid[x][y] = min(grid[x][y], t);

        // 标记四周 4 个点
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= 0 && nx < MAXN && ny >= 0 && ny < MAXN) {
                grid[nx][ny] = min(grid[nx][ny], t);
            }
        }
    }

    cout << bfs() << endl;

    return 0;
}
posted @ 2026-01-11 00:14  AnoSky  阅读(10)  评论(0)    收藏  举报