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:
- The number of rows and columns of
grid
will each be in the range[1, 50]
. - Each
grid[i][j]
will be either0
or1
. - Throughout the described process, there is always a contiguous viral region that will infect strictly more uncontaminated squares in the next round.
先BFS得到所有可能添加wall的地方,然后选取影响最大的,将wall里面的设为0,同时其他virus扩展
一直循环,找到不需要添加wall
class Solution:
def containVirus(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
n,nn=len(grid),len(grid[0])
hor_dirs, vert_dirs=[[-1,0],[1,0]], [[0,-1],[0,1]]
dirs=[[-1,0],[1,0],[0,-1],[0,1]]
hor_walls, vert_walls = set(), set()
def bfs():
m=[[0 for i in range(nn)] for j in range(n)]
cnt,h_walls,v_walls=[],[],[]
c=1
for i in range(n):
for j in range(nn):
if m[i][j]==1: continue
m[i][j]=1
if grid[i][j]>0:
t,h_wall,v_wall = 0,[],[]
c += 1
q=[[i,j]]
while len(q):
x,y=q.pop()
grid[x][y]=c
for d in hor_dirs:
ii,jj=x+d[0],y+d[1]
if ii<0 or jj<0 or ii>=n or jj>=nn: continue
'''do sth about wall here'''
if grid[ii][jj]==0:
t += 1
h_wall.append('%d_%d'%(min(ii,x),y))
if m[ii][jj]==1 or grid[ii][jj]==0: continue
m[ii][jj]=1
q.append([ii,jj])
for d in vert_dirs:
ii,jj=x+d[0],y+d[1]
if ii<0 or jj<0 or ii>=n or jj>=nn: continue
if grid[ii][jj]==0:
t += 1
v_wall.append('%d_%d'%(x,min(jj,y)))
if m[ii][jj]==1 or grid[ii][jj]==0: continue
m[ii][jj]=1
q.append([ii,jj])
cnt.append(t)
h_walls.append(h_wall)
v_walls.append(v_wall)
return cnt,h_walls,v_walls
# ret=0
while 1:
regions,h_walls,v_walls = bfs()
if len(regions)==0 or (len(regions)==1 and regions[0]==0): break
maxReg, idx = 0, -1
for i in range(len(regions)):
if regions[i]>maxReg:
maxReg=regions[i]
idx=i
# ret+=maxReg
tmp_modify=[]
for i in range(n):
for j in range(nn):
if grid[i][j]==0: continue
if grid[i][j]==idx+2:
grid[i][j]=0
else:
tmp_modify.append([i,j])
for d in dirs:
ii,jj=i+d[0],j+d[1]
if ii<0 or jj<0 or ii>=n or jj>=nn: continue
tmp_modify.append([ii,jj])
for i, j in tmp_modify:
grid[i][j]=1
# wall
for w in h_walls[idx]: hor_walls.add(w)
for w in v_walls[idx]: vert_walls.add(w)
return len(hor_walls)+len(vert_walls)
s=Solution()
#print(s.containVirus([[1]]))
#print(s.containVirus([[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]]))
print(s.containVirus([[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,1,0,0],[1,0,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,1,0,0,0],[0,0,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,1,0],[0,0,0,0,1,0,1,0,0,0],[0,0,0,0,0,0,0,0,0,0]]))