兔子屋 | Google Kickstart 2021 A 轮
芭芭拉去年在学校取得了很好的成绩,所以她的父母决定送她一只宠物兔子。她非常兴奋,为兔子建造了一个房子,可以看作是一个 RR 行和 CC 列的 2D 网格。
兔子喜欢跳跃,所以芭芭拉在网格的几个单元格上堆放了几个盒子。每个盒子都是一个具有相同尺寸的立方体,它们与网格单元格的尺寸完全匹配。
然而,芭芭拉很快意识到兔子跳高 11 格可能很危险,所以她决定通过对房子进行一些调整来避免这种情况。对于每一对相邻的单元格,芭芭拉希望它们的绝对高度差最多为 11 个盒子。如果两个单元共享一个公共边,则认为它们是相邻的。
由于所有盒子都是强力胶合的,Barbara 无法移除最初存在的任何盒子,但她可以在它们上面添加盒子。她可以添加任意数量的框,添加任意数量的单元格(可能为零)。帮助她确定要添加的最小盒子总数是多少,这样兔子的房子就安全了。
或者
给定一个R行M列的矩阵。仅通过增加单元格值,使相邻单元格之间的绝对差值小于或等于 1。应最小化在单元格上完成的总增量。任务是返回完成的最小增量操作。
例子:
Input: [[0 0 0],
[0 2 0],
[0 0 0]]
Output: 4
Explanation: the cell in the middle of the grid has an absolute difference in height of 2, the height of all its four adjacent cells is increased by exactly 1 unit so that the absolute difference between
any pair of adjacent cells will be at most 1. Resultant matrix will be:
[[0 1 0],
[1 2 1],
[0 1 0]]
Input: [[1 0 5 4 2],
[1 5 6 4 8],
[2 3 4 2 1],
[2 3 4 9 8]]
Output: 52
Explanation: Resultant matrix will be: [[3 4 5 6 7],
[4 5 6 7 8 ],
[5 6 7 8 7],
[6 7 8 9 8]]
方法:给定 问题 可以使用多源dijkstra算法解决。方法是将具有最大值的单元存储在优先级队列中,一个一个地弹出优先级队列并相应地更新相邻的单元格,在更新单元格值的同时我们也会更新我们的优先级队列。
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
void solve(long long int r, long long int c,
vector >& grid)
{
priority_queue > >
pq;
for (long long int i = 0; i < r; i++) {
for (long long int j = 0; j < c; j++) {
pq.push(make_pair(grid[i][j],
make_pair(i, j)));
}
}
long long int res = 0;
while (!pq.empty()) {
long long int height = pq.top().first,
i = pq.top().second.first,
j = pq.top().second.second;
pq.pop();
if (height != grid[i][j])
continue;
if (i == 0) {
// Down
if (i != r - 1) {
if (grid[i + 1][j] < height - 1) {
res += height - 1 - grid[i + 1][j];
grid[i + 1][j] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i + 1, j)));
}
}
// Left
if (j != 0) {
if (grid[i][j - 1] < height - 1) {
res += height - 1 - grid[i][j - 1];
grid[i][j - 1] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i, j - 1)));
}
}
// Right
if (j != c - 1) {
if (grid[i][j + 1] < height - 1) {
res += height - 1 - grid[i][j + 1];
grid[i][j + 1] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i, j + 1)));
}
}
}
else if (i == r - 1) {
// Up
if (i != 0) {
if (grid[i - 1][j] < height - 1) {
res += height - 1 - grid[i - 1][j];
grid[i - 1][j] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i - 1, j)));
}
}
// Left
if (j != 0) {
if (grid[i][j - 1] < height - 1) {
res += height - 1 - grid[i][j - 1];
grid[i][j - 1] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i, j - 1)));
}
}
// Right
if (j != c - 1) {
if (grid[i][j + 1] < height - 1) {
res += height - 1 - grid[i][j + 1];
grid[i][j + 1] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i, j + 1)));
}
}
}
else {
// Down
if (grid[i + 1][j] < height - 1) {
res += height - 1 - grid[i + 1][j];
grid[i + 1][j] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i + 1, j)));
}
// Up
if (grid[i - 1][j] < height - 1) {
res += height - 1 - grid[i - 1][j];
grid[i - 1][j] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i - 1, j)));
}
// Left
if (j != 0) {
if (grid[i][j - 1] < height - 1) {
res += height - 1 - grid[i][j - 1];
grid[i][j - 1] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i, j - 1)));
}
}
// Right
if (j != c - 1) {
if (grid[i][j + 1] < height - 1) {
res += height - 1 - grid[i][j + 1];
grid[i][j + 1] = height - 1;
pq.push(make_pair(height - 1,
make_pair(i, j + 1)));
}
}
}
}
cout << res;
}
// Driver code
int main()
{
long long int r = 4, c = 5;
vector > grid{ { 1, 0, 5, 4, 2 },
{ 1, 5, 6, 4, 8 },
{ 2, 3, 4, 2, 1 },
{ 2, 3, 4, 9, 8 } };
solve(r, c, grid);
}
52
时间复杂度: O(RM * Log(RM))
辅助空间: O(RM)