• poj 3669 火星撞地球问题 bfs算法


    题意:火星撞地球,你要跑到一个永远安全的地方,求最短时间

    思路:bfs+预处理

      这题的数据量比较大,所以需要进行预处理

    1. 对每个位置设上时间(被撞的最早时间) 未被撞的设为-1

      for (int j = 0; j<5; j++) { //预处理
      int dx = x + dir[j][0], dy = y + dir[j][1];
      if (dx < 0 || dx >= maxn || dy < 0 || dy >= maxn) continue;
      g[dx][dy] = g[dx][dy] == -1 ? d : min(g[dx][dy], d);
      }

    2. 进队列的时候时间要+1,最先到达安全的地方为最短时间

    解决问题的代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <cmath>
    #include <cstdlib>
    #include <ctime>
    #include <stack>
    using namespace std;
    #define INF 0x7fffffff
    #define LL long long
    const int maxn = 1000 + 10;
    
    struct node { int x, y, time; };                            //点结构体
    int g[maxn][maxn];                                         //
    int dir[5][2] = { 0, 0, 0, 1, 0, -1, 1, 0, -1, 0 };          //方向数组
    
    int bfs() {
        if (g[0][0] == 0) return -1;                            //从(0,0)开始搜
        if (g[0][0] == -1) return 0;                            //起点安全,不用躲了
        node tmp, now;
        tmp.x = tmp.y = tmp.time = 0;
        queue<node> q;
        q.push(tmp);
        while (!q.empty()) {
            now = q.front();
            q.pop();
            for (int i = 0; i<5; i++) {
                tmp.x = now.x + dir[i][0], tmp.y = now.y + dir[i][1];
                tmp.time = now.time + 1;
                if (tmp.x < 0 || tmp.y < 0 || tmp.x >= maxn || tmp.y >= maxn) continue;
                if (g[tmp.x][tmp.y] == -1) return tmp.time;
                if (tmp.time >= g[tmp.x][tmp.y]) continue;
                g[tmp.x][tmp.y] = tmp.time;
                q.push(tmp);
            }
        }
        return -1;
    }
    
    int main() {
        int n, x, y, d;
        while (scanf("%d", &n) != EOF) {
            memset(g, -1, sizeof(g));
            for (int i = 0; i<n; i++) {
                scanf("%d%d%d", &x, &y, &d);
                for (int j = 0; j<5; j++) {                                //预处理
                    int dx = x + dir[j][0], dy = y + dir[j][1];
                    if (dx < 0 || dx >= maxn || dy < 0 || dy >= maxn) continue;
                    g[dx][dy] = g[dx][dy] == -1 ? d : min(g[dx][dy], d);
                }
            }
            printf("%d
    ", bfs());
        }
        return 0;
    }
    君子知命不惧,自当日日自新
  • 相关阅读:
    并发编程(2)-进程、并发和并行讲解
    并发编程(5)-管道、数据共享、进程池
    并发编程(4)-进程中的锁、信号量、 事件和队列
    人工智能及数学运算的基础方法
    并发编程(3)-进程模块
    判断一个数是否是水仙花数
    js中隐式类型转换测试
    webpack使用webpack-dev-middleware进行热重载
    网页打包安卓APP流程
    「postgres」查看数据库连接数
  • 原文地址:https://www.cnblogs.com/xuxiaojin/p/9406442.html
Copyright © 2020-2023  润新知