zoukankan      html  css  js  c++  java
  • 牛客算法周周练17D

    在这里插入图片描述在这里插入图片描述

    题目大意:

    给出一张n * m的地图,每经过一个建筑都需要一定的时间,而经过ABC要花费100,要求输出从S到E的最短时间。

    解题思路:

    思路一:dfs剪枝
    输入地图的时候用char输入,然后转成int型即可,然后dfs跑图,因为有多条路到达E而取最短,所以维护一个最小值ans,如果当前没到E,而步数 >= ans,则return,如果当前到了,则ans和s取一个最小值。AC代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <map>
    #include <set>
    #include <cstring>
    using namespace std;
    const int N = 35;
    int mp[N][N], mmin = 0x7fffffff, n, m;
    int x, y, xx, yy;
    int xn[4]={-1,1,0,0},ynn[4]={0,0,-1,1};//这里用一维比二维快,如果用二维就会TLE
    bool book[N][N];
    char st;
    void dfs(int x0, int y0, int s)
    {
        if (x0 == xx && y0 == yy)
        {
            mmin = min(s, mmin);
            return;
        }
        if (s >= mmin)//剪枝
          return;
        for (int k = 0; k < 4; k ++)
        {
            int tx = x0 + xn[k];
            int ty = y0 + ynn[k];
            if (tx < 1 || tx > n || ty < 1 || ty > m || book[tx][ty])
              continue;
            book[tx][ty] = true;
            dfs(tx, ty, s + mp[tx][ty]);
            book[tx][ty] = false;
        }
        return;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> n >> m;
        for (int i = 1; i <= n; i ++)
            for (int j = 1; j <= m; j ++)
            {
                cin >> st;
                if (isdigit(st))
                  mp[i][j] = st - '0';
                else if (st == 'A' || st == 'B' || st == 'C')
                    mp[i][j] = 100;
                else if (st == 'S')
                    x = i, y = j;
                else if (st == 'E')
                    xx = i, yy = j;;
            }
        book[x][y] = true;
        dfs(x, y, 0);
        cout << mmin << endl;
        return 0;
    }
    

    dfs思路学到了开两个一维数组表示方向比二维的[4][2]要快,如果一维就不会超时,二维则会TLE

    思路二:优先队列优化bfs
    用优先队列存放当前的点,用权值排序,以保证当前走到的点一定是多条路之中最小的,那么第一次到E点的值即为最小值。AC代码:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <map>
    #include <set>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int N = 35;
    struct node
    {
        int x, y, sum;
        bool operator < (const node &t)const
        {
            return sum > t.sum;
        }
    };
    int mp[N][N], ans, n, m, x, y, xx, yy;
    int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    bool book[N][N];
    char st;
    void bfs(int x, int y)
    {
        priority_queue<node > q;
        q.push({x, y, 0});
        book[x][y] = true;
        while (!q.empty())
        {
            auto tt = q.top(); q.pop();
            if (tt.x == xx && tt.y == yy)
            {
                ans = tt.sum;
                return;
            }
            for (int k = 0; k < 4; k ++)
            {
                int nx = tt.x + dir[k][0];
                int ny = tt.y + dir[k][1];
                if (nx < 1 || nx > n || ny < 1 || ny > m || book[nx][ny])
                  continue;
                book[nx][ny] = true;
                q.push({nx, ny, tt.sum + mp[nx][ny]});
            }
        }
        return;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin >> n >> m;
        for (int i = 1; i <= n; i ++)
            for (int j = 1; j <= m; j ++)
            {
                cin >> st;
                if (isdigit(st))
                  mp[i][j] = st - '0';
                else if (st == 'A' || st == 'B' || st == 'C')
                    mp[i][j] = 100;
                else if (st == 'S')
                    x = i, y = j;
                else if (st == 'E')
                    xx = i, yy = j;;
            }
        book[x][y] = true;
        bfs(x, y);
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    利用string 字符串拷贝
    新手学vim配置
    进程描述符task_struct
    并查集
    堆Heap
    Bitset位图
    排序
    sql时间查询
    javascript 中的 call
    css 笔记——设置禁用中文输入法
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294174.html
Copyright © 2011-2022 走看看