力扣 749. 隔离病毒

题目:

病毒扩散得很快,现在你的任务是尽可能地通过安装防火墙来隔离病毒。

假设世界由二维矩阵组成,0 表示该区域未感染病毒,而 1 表示该区域已感染病毒。可以在任意 2 个四方向相邻单元之间的共享边界上安装一个防火墙(并且只有一个防火墙)。

每天晚上,病毒会从被感染区域向相邻未感染区域扩散,除非被防火墙隔离。现由于资源有限,每天你只能安装一系列防火墙来隔离其中一个被病毒感染的区域(一个区域或连续的一片区域),且该感染区域对未感染区域的威胁最大且保证唯一。

你需要努力使得最后有部分区域不被病毒感染,如果可以成功,那么返回需要使用的防火墙个数; 如果无法实现,则返回在世界被病毒全部感染时已安装的防火墙个数。

示例 1:

输入: 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]]
输出: 10
说明:
一共有两块被病毒感染的区域: 从左往右第一块需要 5 个防火墙,同时若该区域不隔离,晚上将感染 5 个未感染区域(即被威胁的未感染区域个数为 5);
第二块需要 4 个防火墙,同理被威胁的未感染区域个数是 4。因此,第一天先隔离左边的感染区域,经过一晚后,病毒传播后世界如下:
[[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]]
第二题,只剩下一块未隔离的被感染的连续区域,此时需要安装 5 个防火墙,且安装完毕后病毒隔离任务完成。

示例 2:

输入: grid = 
[[1,1,1],
 [1,0,1],
 [1,1,1]]
输出: 4
说明: 
此时只需要安装 4 面防火墙,就有一小区域可以幸存,不被病毒感染。
注意不需要在世界边界建立防火墙。

示例 3:

输入: 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]]
输出: 13
说明: 
在隔离右边感染区域后,隔离左边病毒区域只需要 2 个防火墙了。

说明:

    grid 的行数和列数范围是 [1, 50]。
     grid[i][j] 只包含 0 或 1 。
    题目保证每次选取感染区域进行隔离时,一定存在唯一一个对未感染区域的威胁最大的区域。

解题思路

1.dfs将每个连通域的节点坐标分别保存

2.计算每个连通域最大可能感染的人数,保存感染人数最大的连通域的下标

3.计算最大感染连通域所需防火墙数量,被防火墙隔离的区域节点值可设置为2

4.进行一轮病毒传播

循环1234,返回结果

下面是代码:

class Solution {
public:
    struct point{
        int x;
        int y;
    };
    vector<vector<point>> virus_area;
    void dfs(vector<vector<int>>& grid,vector<point> &area_point,vector<vector<bool>> &visited,int a,int b)
    {      
        int row=grid.size();
        int col=grid[0].size();
        int vary[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
        visited[a][b]=true;
        point p;
        p.x=a;
        p.y=b;
        area_point.push_back(p);
        for(int i=0;i<4;i++)
        {
            int x=a+vary[i][0];
            int y=b+vary[i][1];
            if(x>=0&&x<row&&y>=0&&y<col&&visited[x][y]==false&&grid[x][y]==1)
            {
                dfs(grid,area_point,visited,x,y);
            }
        }
    }
    int defense_virus(vector<vector<int>>& grid)
    {
        virus_area.clear();
        int row=grid.size();
        int col=grid[0].size();
        vector<point> area_point;
        vector<vector<bool>> visited(row,vector<bool>(col,false));
        for(int i=0;i<row;i++)
        {
            for(int j=0;j<col;j++)
            {                
                if(grid[i][j]==1&&visited[i][j]==false)
                {
                    area_point.clear();
                    dfs(grid,area_point,visited,i,j);
                    virus_area.push_back(area_point);
                }              
            }
        }
        int max_index=-1;
        int max_infect_num=0;
        int N=virus_area.size();
        int vary[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
        for(int i=0;i<N;i++)
        {
            vector<vector<int>> temp_grid=grid;
            int infect_num=0;
            int len=virus_area[i].size();
            for(int j=0;j<len;j++)
            {
                for(int k=0;k<4;k++)
                {
                    int x=virus_area[i][j].x+vary[k][0];
                    int y=virus_area[i][j].y+vary[k][1];
                    if(x>=0&&x<row&&y>=0&&y<col&&grid[x][y]==0)
                    {
                        infect_num++;
                        grid[x][y]=1;
                    }
                }
            }
            if(infect_num>max_infect_num)
            {
                max_infect_num=infect_num;
                max_index=i;
            }
            grid=temp_grid;
        }
        if(max_infect_num<=0)return 0;
        int size=virus_area[max_index].size();
        int fire_wall=0;
        for(int i=0;i<size;i++)
        {
            point temp=virus_area[max_index][i];
            for(int k=0;k<4;k++)
                {
                    int x=temp.x+vary[k][0];
                    int y=temp.y+vary[k][1];
                    if(x>=0&&x<row&&y>=0&&y<col&&grid[x][y]==0)
                    {
                        fire_wall++;
                    }
                }
            grid[temp.x][temp.y]=2;
        }
        virus_area.erase(virus_area.begin()+max_index);
        int L=virus_area.size();
        for(int i=0;i<L;i++)
        {
            int s=virus_area[i].size();
            for(int j=0;j<s;j++)
            {
                point temp=virus_area[i][j];
                for(int k=0;k<4;k++)
                {
                    int x=temp.x+vary[k][0];
                    int y=temp.y+vary[k][1];
                    if(x>=0&&x<row&&y>=0&&y<col&&grid[x][y]==0)
                    {
                        grid[x][y]=1;
                    }
                }
            }
        }
        return fire_wall;
    }
    int containVirus(vector<vector<int>>& grid) {
        int sum_fire_wall=0;
        int temp=0;
        while(true)
        {
            temp=defense_virus(grid);
            if(temp==0)break;
            sum_fire_wall+=temp;
        }
        return sum_fire_wall;
    }
};

emm实际效果有点差,但没想到太好的解决办法0.0

计算机201 LW

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值