搜索—The Wedding Juicer G

[USACO05JAN] The Wedding Juicer G

题目描述

约翰的奶牛们找到了一份不错的兼职一设计冲压式榨汁机.榨汁机设计如下:

一个 \(W \times H\) 的底座(\(3\leq W,H \leq 300\)),每一个 \(1 \times 1\) 的方格上都放有一个高度为 \(B\)\(1 \leq B \leq 10^9\))的柱子,用来榨汁。假设柱子之间都被完美地粘合了,这样水不会顺着柱子与柱子之间的空隙流走。

但是约翰一直不知道,这么一个榨汁机,到底能装多少果汁?假设榨汁机周围没有任何东西,也就是说,边界上的水都会流走,有些榨汁机则根本不能装下任何的果汁。

输入格式

第一行两个整数 \(W\)\(H\)

接下来 \(H\) 行,每行 \(W\) 个数字,代表了高度。

输出格式

输出最多能装多少果汁。

样例 #1

样例输入 #1

4 5
5 8 7 7
5 2 1 5
7 1 7 1
8 9 6 9
9 8 9 9

样例输出 #1

12

分析

这题也属于洪水填充问题,如果逐个检查柱子分析会很复杂,我们可以从柱子的边界开始,找到边界最低的柱子,检查他的邻居柱子判断能否储存,并且更新边界,使边界保持高柱子的值,这样不断缩小边界,可以快速检查完柱子。

代码实现

#include <iostream>
#include <queue>
using namespace std;

int x, y, ans = 0;
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int mp[305][305];
bool mark[305][305];

struct node {
    int i;
    int j;
    int h;

    bool operator<(const node tmp) const {
        return h > tmp.h;
    }
};

priority_queue<node> q;

int bfs() {
    node next;
    while (!q.empty()) {
        node cur = q.top();
        q.pop();
        for (int t = 0; t < 4; t++) {
            next.i = cur.i + dir[t][0];
            next.j = cur.j + dir[t][1];
            next.h = mp[next.i][next.j];
            int hh = cur.h;
            if (next.i > 0 && next.j > 0 && next.i <= y && next.j <= x && !mark[next.i][next.j]) {
                if (next.h < hh) {
                    ans += hh - next.h;
                    next.h = hh;
                }
                mark[next.i][next.j] = 1;
                q.push(next);
            }
        }
    }
    return ans;
}

int main() {
    cin >> x >> y;
    node block;
    for (int i = 1; i <= y; i++)
        for (int j = 1; j <= x; j++) {
            cin >> mp[i][j];
            if (i == 1 || j == 1 || i == y || j == x) {
                mark[i][j] = 1;
                block.i = i;
                block.j = j;
                block.h = mp[i][j];
                q.push(block);
            }
        }
    cout << bfs();
    return 0;
}
posted @ 2023-08-22 03:36  LongDz  阅读(56)  评论(0)    收藏  举报