搜索—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;
}

浙公网安备 33010602011771号