A virus is spreading rapidly, and your task is to quarantine the infected area by installing walls.

The world is modeled as a 2-D array of cells, where 0 represents uninfected cells, and 1 represents cells contaminated with the virus. A wall (and only one wall) can be installed between any two 4-directionally adjacent cells, on the shared boundary.

Every night, the virus spreads to all neighboring cells in all four directions unless blocked by a wall. Resources are limited. Each day, you can install walls around only one region -- the affected area (continuous block of infected cells) that threatens the most uninfected cells the following night. There will never be a tie.

Can you save the day? If so, what is the number of walls required? If not, and the world becomes fully infected, return the number of walls used.

Example 1:

Input: grid =
[[0,1,0,0,0,0,0,1],
[0,1,0,0,0,0,0,1],
[0,0,0,0,0,0,0,1],
[0,0,0,0,0,0,0,0]]
Output: 10
Explanation:
There are 2 contaminated regions.
On the first day, add 5 walls to quarantine the viral region on the left. The board after the virus spreads is: [[0,1,0,0,0,0,1,1],
[0,1,0,0,0,0,1,1],
[0,0,0,0,0,0,1,1],
[0,0,0,0,0,0,0,1]] On the second day, add 5 walls to quarantine the viral region on the right. The virus is fully contained.

Example 2:

Input: grid =
[[1,1,1],
[1,0,1],
[1,1,1]]
Output: 4
Explanation: Even though there is only one cell saved, there are 4 walls built.
Notice that walls are only built on the shared boundary of two different cells.

Example 3:

Input: grid =
[[1,1,1,0,0,0,0,0,0],
[1,0,1,0,1,1,1,1,1],
[1,1,1,0,0,0,0,0,0]]
Output: 13
Explanation: The region on the left only builds two new walls.

Note:

  1. The number of rows and columns of grid will each be in the range [1, 50].
  2. Each grid[i][j] will be either 0 or 1.
  3. Throughout the described process, there is always a contiguous viral region that will infect strictly more uncontaminated squares in the next round.

Python:

class Solution(object):
def containVirus(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
directions = [(0, 1), (0, -1), (-1, 0), (1, 0)] def dfs(grid, r, c, lookup, regions, frontiers, perimeters):
if (r, c) in lookup:
return
lookup.add((r, c))
regions[-1].add((r, c))
for d in directions:
nr, nc = r+d[0], c+d[1]
if not (0 <= nr < len(grid) and \
0 <= nc < len(grid[r])):
continue
if grid[nr][nc] == 1:
dfs(grid, nr, nc, lookup, regions, frontiers, perimeters)
elif grid[nr][nc] == 0:
frontiers[-1].add((nr, nc))
perimeters[-1] += 1 result = 0
while True:
lookup, regions, frontiers, perimeters = set(), [], [], []
for r, row in enumerate(grid):
for c, val in enumerate(row):
if val == 1 and (r, c) not in lookup:
regions.append(set())
frontiers.append(set())
perimeters.append(0)
dfs(grid, r, c, lookup, regions, frontiers, perimeters) if not regions: break triage_idx = frontiers.index(max(frontiers, key = len))
for i, region in enumerate(regions):
if i == triage_idx:
result += perimeters[i]
for r, c in region:
grid[r][c] = -1
continue
for r, c in region:
for d in directions:
nr, nc = r+d[0], c+d[1]
if not (0 <= nr < len(grid) and \
0 <= nc < len(grid[r])):
continue
if grid[nr][nc] == 0:
grid[nr][nc] = 1 return result

C++:

class Solution {
public:
int containVirus(vector<vector<int>>& grid) {
int res = 0, m = grid.size(), n = grid[0].size();
vector<vector<int>> dirs{{-1,0},{0,1},{1,0},{0,-1}};
while (true) {
unordered_set<int> visited;
vector<vector<vector<int>>> all;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == 1 && !visited.count(i * n + j)) {
queue<int> q{{i * n + j}};
vector<int> virus{i * n + j};
vector<int> walls;
visited.insert(i * n + j);
while (!q.empty()) {
auto t = q.front(); q.pop();
for (auto dir : dirs) {
int x = (t / n) + dir[0], y = (t % n) + dir[1];
if (x < 0 || x >= m || y < 0 || y >= n || visited.count(x * n + y)) continue;
if (grid[x][y] == -1) continue;
else if (grid[x][y] == 0) walls.push_back(x * n + y);
else if (grid[x][y] == 1) {
visited.insert(x * n + y);
virus.push_back(x * n + y);
q.push(x * n + y);
}
}
}
unordered_set<int> s(walls.begin(), walls.end());
vector<int> cells{(int)s.size()};
all.push_back({cells ,walls, virus});
}
}
}
if (all.empty()) break;
sort(all.begin(), all.end(), [](vector<vector<int>> &a, vector<vector<int>> &b) {return a[0][0] > b[0][0];});
for (int i = 0; i < all.size(); ++i) {
if (i == 0) {
vector<int> virus = all[0][2];
for (int idx : virus) grid[idx / n][idx % n] = -1;
res += all[0][1].size();
} else {
vector<int> wall = all[i][1];
for (int idx : wall) grid[idx / n][idx % n] = 1;
}
}
}
return res;
}
};

   

All LeetCode Questions List 题目汇总

最新文章

  1. C# DllImport用法和路径问题
  2. 年前辞职-WCF入门学习(1,2)
  3. destoon 会员整合Ucenter/Discuz!/PHPWind教程
  4. MySQL: ON DUPLICATE KEY UPDATE 用法 避免重复插入数据
  5. netbeans 优化设置
  6. FileReader上传图片
  7. 柔性数组-读《深度探索C++对象模型》有感 (转载)
  8. CAD 致命错误
  9. Core Data Stack学习笔记
  10. 【Nginx】磁盘文件写入飞地发
  11. 移动端开发(一. Viewport(视窗))
  12. WEB前端:浏览器(IE+Chrome+Firefox)常见兼容问题处理--02
  13. C++ Primer 有感(复制控制)
  14. Python并发编程的几篇文章
  15. 将CSV文件写入MySQL
  16. C# 锁
  17. web项目访问地址前添加小图片
  18. Java NIO 详解(一)
  19. MYSQL优化优化再优化!
  20. 使用findbugs为自己的代码review

热门文章

  1. SD介绍
  2. less-5
  3. Convert 输入字符串的格式不正确
  4. 斜率优化板题 HDU 3507 Print Article
  5. SpringCloud组件Eureka
  6. java代码操作Redis
  7. 3-微信小程序开发(小程序的目录结构说明)
  8. 洛谷 P2813【母舰】 题解
  9. 获取页面scroll高度
  10. 刷题记录:[CISCN2019 华北赛区 Day2 Web1]Hack World