1 条题解

  • 1
    @ 2025-10-29 22:09:45

    代码说明:

    使用二维数组记录每个格子的最早被摧毁时间 采用BFS算法从起点(0,0)开始搜索逃生路径 移动规则:只能在被摧毁前的时间进入格子,且不能重复访问 找到第一个永远不会被摧毁的格子即为安全点 时间复杂度为O(300*300),在给定约束下可行 该算法能正确处理样例输入,输出芙蓉哥哥逃生的最短时间。

    #include <iostream>
    #include <queue>
    #include <vector>
    #include <climits>
    using namespace std;
    
    const int MAX = 302;
    const int INF = INT_MAX;
    
    // 记录每个格子的最早被摧毁时间
    int destroyTime[MAX][MAX];
    // 记录每个位置的最早到达时间
    int reachTime[MAX][MAX];
    
    // 方向数组:上、右、下、左
    int dx[4] = {0, 1, 0, -1};
    int dy[4] = {1, 0, -1, 0};
    
    struct Point {
        int x, y, time;
        Point(int _x, int _y, int _t) : x(_x), y(_y), time(_t) {}
    };
    
    int main() {
        int M;
        cin >> M;
        
        // 初始化摧毁时间为无穷大
        for (int i = 0; i < MAX; i++) {
            for (int j = 0; j < MAX; j++) {
                destroyTime[i][j] = INF;
                reachTime[i][j] = INF;
            }
        }
        
        // 读取流星信息并更新摧毁时间
        for (int i = 0; i < M; i++) {
            int x, y, t;
            cin >> x >> y >> t;
            
            // 流星撞击点及其四个相邻格子都会被摧毁
            destroyTime[x][y] = min(destroyTime[x][y], t);
            if (x > 0) destroyTime[x-1][y] = min(destroyTime[x-1][y], t);
            if (y > 0) destroyTime[x][y-1] = min(destroyTime[x][y-1], t);
            destroyTime[x+1][y] = min(destroyTime[x+1][y], t);
            destroyTime[x][y+1] = min(destroyTime[x][y+1], t);
        }
        
        // 如果起点(0,0)在时刻0就被摧毁,直接输出-1
        if (destroyTime[0][0] == 0) {
            cout << -1 << endl;
            return 0;
        }
        
        // BFS搜索
        queue<Point> q;
        q.push(Point(0, 0, 0));
        reachTime[0][0] = 0;
        
        int result = -1;
        
        while (!q.empty()) {
            Point current = q.front();
            q.pop();
            
            int x = current.x;
            int y = current.y;
            int currentTime = current.time;
            
            // 如果当前位置永远不会被摧毁,则找到安全点
            if (destroyTime[x][y] == INF) {
                result = currentTime;
                break;
            }
            
            // 尝试四个方向的移动
            for (int i = 0; i < 4; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];
                int nextTime = currentTime + 1;
                
                // 检查边界和可达性
                if (nx >= 0 && ny >= 0 && nx < MAX && ny < MAX) {
                    // 目标格子必须在被摧毁之前到达,且未被访问过
                    if (nextTime < destroyTime[nx][ny] && 
                        nextTime < reachTime[nx][ny]) {
                        reachTime[nx][ny] = nextTime;
                        q.push(Point(nx, ny, nextTime));
                    }
                }
            }
        }
        
        cout << result << endl;
        return 0;
    }
    
    
    
    • 1

    信息

    ID
    2438
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    373
    已通过
    60
    上传者