749. Contain Virus

本文介绍了一种通过建立二维网格模型来模拟病毒扩散的方法,并提出了一种通过安装隔离墙来有效控制疫情蔓延的策略。文章详细阐述了如何通过广度优先搜索(BFS)寻找最优隔离方案,以最小化病毒传播的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.

思路比较明显,但是比较烦

先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]]))



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值