• POJ 3669 Meteor Shower 题解 《挑战程序设计竞赛》


    题目链接

    http://poj.org/problem?id=3669

    题意:

    这个同学发现流星雨要来了,会对地球造成伤害于是决定逃跑。N颗流星会不定时降落在坐标轴第一象限300*300内的点上。给出每颗流星降落的坐标和时刻,求这个同学能否成功逃跑,能的话用时多少。

    思路:

    略有一点tricky,无法变通了(@﹏@)~。看了码农场的代码

    这道题没有给出地图,所以需要自己生成地图。

    关键的点在于:在生成地图的时候,将每个点的初始值设为无穷大(表示不会有流星),将要被摧毁的点设置为流星降落的时刻。如果原点从一开始就被炸毁,那么直接死亡,否则开始BFS。

    从原点开始广度优先地游荡,判断要不要到一个点的依据是该点在地图内,并且该点此前未被访问过,也未被炸毁(可能在将来被炸毁)。每到一个点,当前时间+1.

    在游荡过程中一旦发现一个点永远不会被炸(>last变量,或者等于INF?),说明找到了活命点,返回当前所用时间。

    如果一直到遍历完毕都找不到这样的点,说明无法逃跑,返回-1。

    代码:

    刚开始提交的时候总是Runtime Error,de了半天发现input数组本应该是50000,设置成了5000……这种粗心的错误要少犯啊

    #include <iostream>
    #include <algorithm>
    #include <stdio.h>   
    #include <memory.h>  
    #include <queue>
    
    using namespace std;
    
    const int MAX_INDEX = 512;
    int eMap[MAX_INDEX][MAX_INDEX];
    bool visited[MAX_INDEX][MAX_INDEX];
    
    struct Meteor {
        int x;
        int y;
        int t;
    };
    
    typedef Meteor P;
    
    Meteor input[50000];
    int n;
    int last = 0;
    
    int dx[5] = {-1, 0, 1, 0, 0};
    int dy[5] = {0, -1, 0, 1, 0};
    
    int bfs() {
        memset(visited, 0, sizeof(visited));
        queue<P> que;
        P cur;
        cur.x = 0;
        cur.y = 0;
        cur.t = 0;
        que.push(cur);
        
        while (que.size()) {        
            for (int i = 0; i < 4; i++) {
                cur = que.front();
                cur.x += dx[i];
                cur.y += dy[i];
                cur.t++;
                if (cur.x >= 0 && cur.y >= 0 && cur.t < eMap[cur.x][cur.y] && !visited[cur.x][cur.y]) {
                    visited[cur.x][cur.y] = true;
                    if (eMap[cur.x][cur.y] > last) {
                        return cur.t;
                    }                
                    que.push(cur);
                }
            }        
            que.pop();
        }
        return -1;
    }
    
    int main() {
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> input[i].x >> input[i].y >> input[i].t;
        }
        
        memset(eMap, 0x7f, sizeof(eMap));   //将地图上所有点的值设为极大值(按题意只需大于1000就可) 
        for (int i = 0; i < n; i++) {       //创建地图 
            last = max(last, input[i].t);   //last变量记录流星下落的最晚时间 
            for (int j = 0; j < 5; j++) {
                int nx = input[i].x + dx[j];
                int ny = input[i].y + dy[j];
                if (nx >= 0 && ny >= 0 && eMap[nx][ny] > input[i].t) {
                    eMap[nx][ny] = input[i].t;
                }
            }     
        }
        
        if (eMap[0][0] == 0) {
            return -1;
        } 
        else { 
            cout << bfs() << endl;
        }
        
        return 0;
    }

    这段代码里的结构体变量Meteor,又被typedef为P,不是多此一举。是因为这个变量有两个用途:

    1 接收输入流,此时x,y代表流星将要下落的坐标,t代表下落时刻;

    2 在BFS的时候,标志该同学此时所处位置,此时x,y代表该同学当前坐标,t代表目前为止所花时间。

    Brilliant!

    感觉自己并写不出来这样的代码...

  • 相关阅读:
    Mysql分布式事务
    Mysql锁
    Mysql事务隔离级别
    java 资源监控
    Mysql子查询
    javaWeb四大域对象
    KVM 迁移
    KVM 虚拟化
    网络基础
    系统简单启动过程
  • 原文地址:https://www.cnblogs.com/carolunar/p/6354375.html
Copyright © 2020-2023  润新知