• AOJ 0558 Cheese 题解 《挑战程序设计竞赛》


    原文链接:
    AOJ0558
    题意:
    在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪。有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪。老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次),且老鼠只能吃硬度不大于当前体力值的奶酪。 
    老鼠从当前格走到相邻的无障碍物的格(上下左右)需要时间1单位,有障碍物的格不能走。走到工厂上时即可吃到该工厂的奶酪,吃奶酪时间不计。问吃遍所有奶酪最少用时。 
    输入:第一行三个整数H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之后H行W列为地图, “.“为空地, ”X“为障碍物,”S“为老鼠洞, 1-N代表硬度为1-N的奶酪的工厂。

    入力例 1
    3 3 1
    S..
    ...
    ..1

    出力例 1
    4

    入力例 2
    4 5 2
    .X..1
    ....X
    .XX.S
    .2.X.

    出力例 2
    12

    入力例 3
    10 10 9
    .X...X.S.X
    6..5X..X1X
    ...XXXX..X
    X..9X...X.
    8.X2X..X3X
    ...XX.X4..
    XX....7X..
    X..X..XX..
    X...X.XX..
    ..X.......

    出力例 3
    91

    思路:

    老鼠初始体力值为1,并且只能吃硬度不大于当前体力值的奶酪,每吃一个奶酪体力值增加1。有N个奶酪,硬度分别为1~N。说明老鼠只能按照1~N的顺序吃。比如有5个奶酪,硬度分别是1、2、3、4、5,老鼠只能按照这个顺序吃,吃完之后的体力值分别为2、3、4、5、6。

    看起来复杂的条件实际上降低了搜索难度,只需将递增的数字当做终点逐个搜索,相当于正常的BFS循环N次。

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <deque>
    
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    typedef pair<int, int> P;
    int h, w, n;
    int sx, sy;
    int gx, gy;
    char cmap[1000][1000];
    int goalSum;
    int goal[10];
    int d[1000][1000];
    int dx[4] = {-1, 0, 1, 0};
    int dy[4] = {0, -1, 0, 1};
    
    int bfs() {
        int res = 0;
        deque<P> que;
        for (int ci = 0; ci < n; ci++) {  //要进行n次循环,寻找n次终点,每次步数计入goal[i], 最后累加起来是res 
            for (int i = 0; i < h; i++) {
                for (int j = 0; j < w; j++) {
                    d[i][j] = INF;
                }
            }
            
            que.push_back(P(sx, sy));
            d[sx][sy] = 0;
            
            while(que.size()) {            
                int x = que.front().first;
                int y = que.front().second;
                
                que.pop_front();
                
                if ((int)cmap[x][y] == 49 + ci) {
                    goal[ci] = d[x][y];
                    sx = x;
                    sy = y;
                    break;
                }
                
                for (int i = 0; i < 4; i++) {
                    int nx = x + dx[i];
                    int ny = y + dy[i];
                    if (nx >=0 && nx < h && ny >= 0 && ny < w && cmap[nx][ny] != 'X' && d[nx][ny] == INF) {
                        que.push_back(P(nx, ny));
                        d[nx][ny] = d[x][y] + 1;
                    }
                }            
            }
            que.clear(); 
            res += goal[ci];
        }
        return res;
    }
    
    int main() {
        cin >> h >> w >> n;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                cin >> cmap[i][j];
                if (cmap[i][j] == 'S') {
                    sx = i;
                    sy = j;
                }
            }
        }
        goalSum = bfs();
        cout << goalSum << endl; //不换行会PE
        return 0;
    }
    • 通常 BFS 使用队列 queue 即可,这里由于多次循环 BFS,每次要清空队列,故用了 STL 的双端队列 deque,clear() 函数用来清空。
    • deque 常用函数有:front(), back(), push_front(), push_back(), pop_front(), pop_back()。头尾均可以访问、添加、删除。
    • d[x][y]在记录起点到某坐标的步数的同时,还起到标志该点是否被搜索过的作用。
    • queue的empty()函数不是用来清空的!是返回该队列是否为空> < (debug了很久_(:зゝ∠)_)
  • 相关阅读:
    众多linux 库及工具意思的解释
    ubuntu root 登录
    Oscillator的参数解释
    世界观和方法论写给学弟学妹的
    元件的降额使用可靠度设计
    电子元件又一话——电感篇
    【转】什么是磁珠(Ferrite Bead 即 FB)
    Digital System Design Guidelines
    几种典型接口的电平标准
    珀耳帖效应
  • 原文地址:https://www.cnblogs.com/carolunar/p/6353956.html
Copyright © 2020-2023  润新知