首页 > 其他分享 >LC 749. 隔离病毒

LC 749. 隔离病毒

时间:2024-07-16 10:43:04浏览次数:12  
标签:LC int 749 isInfected vector bfsQueue nextJ size 隔离

用时:2h 5m
初看以为门的数量=扩散数量。后来跑测试发现,可能扩散数量会有重和。所以门的数量>=扩散数量。优化的话,可以省去expand的bfs,一次bfs,记录当前和max的扩散量和已有量

class Solution {
public:
	int doorNumber = 0;
	enum InfectedType
	{
		clean,
		isInfecting,
		blocked,
		willInfect,
	};
	int containVirus(vector<vector<int>>& isInfected) {
		int maxTotalOutBlock = -1;
		int answer = 0;
		while (maxTotalOutBlock != 0) {
			auto [maxTotalOutBlockIn, answerPoints] =ContainVirusRecurrence(isInfected);
			maxTotalOutBlock = maxTotalOutBlockIn.second;
			/*cout << "x=" << maxTotalOutBlock << endl;
			for (int i = 0; i < isInfected.size(); i++)
			{
				for (int j = 0; j < isInfected[0].size(); j++)
				{
					cout << isInfected[i][j];
				}
				cout << endl;
			}*/
			answer += maxTotalOutBlock;
			SetInfectedToNextStage(isInfected,answerPoints);
			Expand(isInfected, answerPoints);
			
		}
		return answer;
	}
	void Expand(vector<vector<int>>& isInfected, vector<pair<int, int>>answerPoints) {
		for (int i = 0; i < isInfected.size(); i++)
		{
			for (int j = 0; j < isInfected[0].size(); j++)
			{
				if (isInfected[i][j] == InfectedType::isInfecting) {
					auto StartBfs = [&]() {
						vector<vector<bool>>isBlockVisited(isInfected.size(), vector<bool>(isInfected[0].size(), false));
						queue<pair<int, int>>bfsQueue;
						vector<pair<int, int>> directions = { {1,0},{-1,0},{0,1},{0,-1} };
						vector<pair<int, int>>point;
						int totalOutBlock = 0, doorNeeded = 0;
						bfsQueue.push({ i,j });
						isBlockVisited[i][j] = true;
						while (bfsQueue.empty() == false)
						{
							point.push_back(bfsQueue.front());
							auto [wi, wj] = bfsQueue.front();
							bfsQueue.pop();
							for (int k = 0; k < directions.size(); k++)
							{
								int nextI = wi + directions[k].first;
								int nextJ = wj + directions[k].second;
								if (nextI < isInfected.size() && nextJ < isInfected[0].size()
									&& nextI >= 0 && nextJ >= 0) {
									if (isBlockVisited[nextI][nextJ])continue;
									isBlockVisited[nextI][nextJ] = true;
									if (isInfected[nextI][nextJ] == InfectedType::clean) {
										isInfected[nextI][nextJ] = InfectedType::willInfect;
									}
									else  if (isInfected[nextI][nextJ] == InfectedType::isInfecting) {
										bfsQueue.push({ nextI,nextJ });
									}
								}
							}
						}
						return pair<pair<int, int>, vector<pair<int, int>>>{ {totalOutBlock, doorNeeded}, point };
					};
					StartBfs();
				}
			}
		}
		for (int i = 0; i < isInfected.size(); i++)
		{
			for (int j = 0; j < isInfected[0].size(); j++)
			{
				if(isInfected[i][j]==InfectedType::willInfect)
				isInfected[i][j] = InfectedType::isInfecting;
			}
		}
	}
	void SetInfectedToNextStage(vector<vector<int>>& isInfected, vector<pair<int, int>>answerPoints) {
		for (int i = 0; i < answerPoints.size(); i++)
		{
			isInfected[answerPoints[i].first][answerPoints[i].second] = InfectedType::blocked;
		}
	}
	pair<pair<int,int>,vector<pair<int,int>>> ContainVirusRecurrence(vector<vector<int>>& isInfected) {
		int maxTotalOutBlock = 0,doorNumber=0;
		vector<pair<int, int>>answerPoints;
		vector<vector<bool>>isInfectedBlockVisited(isInfected.size(), vector<bool>(isInfected[0].size(), false));
		for (int i = 0; i < isInfected.size(); i++)
		{
			for (int j = 0; j < isInfected[0].size(); j++)
			{
				if (isInfected[i][j]==InfectedType::isInfecting&& isInfectedBlockVisited[i][j]==false) {
					auto StartBfs = [&]() {
						queue<pair<int, int>>bfsQueue;
						vector<pair<int, int>> directions = { {1,0},{-1,0},{0,1},{0,-1} };
						vector<pair<int, int>>point;
						vector<vector<bool>>isBlockVisited(isInfected.size(), vector<bool>(isInfected[0].size(), false));
						int totalOutBlock = 0,doorNeeded=0;
						bfsQueue.push({ i,j });
						isBlockVisited[i][j] = true;
						while (bfsQueue.empty() == false)
						{
							point.push_back(bfsQueue.front());
							auto [wi, wj] = bfsQueue.front();
							isInfectedBlockVisited[wi][wj] = true;
							bfsQueue.pop();
							for (int k = 0; k < directions.size(); k++)
							{
								int nextI = wi + directions[k].first;
								int nextJ = wj + directions[k].second;
								//cout <<"x =" << nextI << ' ' << nextJ << endl;
								if (nextI < isInfected.size() && nextJ < isInfected[0].size()
									&& nextI>=0 && nextJ>=0) {
									//cout << nextI << ' ' << nextJ << endl;
									if (isInfected[nextI][nextJ] == InfectedType::clean) {
										//cout << "s =" << nextI << ' ' << nextJ << endl;
										++doorNeeded;
									}
									if (isBlockVisited[nextI][nextJ])continue;
									isBlockVisited[nextI][nextJ] = true;
									if (isInfected[nextI][nextJ] == InfectedType::clean) {
										++totalOutBlock;
									}
									else  if (isInfected[nextI][nextJ] == InfectedType::isInfecting) {
										bfsQueue.push({ nextI,nextJ });
									}
								}
							}
						}
						return pair<pair<int, int>, vector<pair<int, int>>>{ {totalOutBlock, doorNeeded}, point };
					};
					auto [oneBlockNeed,tempAnswerPoints] = StartBfs();
					/*cout << "xxx=" << oneBlockNeed.first << endl;
					cout <<"xjx="<< i<<' '<<j << endl;*/
					if (oneBlockNeed.first > maxTotalOutBlock) {

						maxTotalOutBlock = oneBlockNeed.first;
						answerPoints.clear();
						answerPoints = tempAnswerPoints;
						doorNumber = oneBlockNeed.second;
					}
				}
			}
		}

		return { {maxTotalOutBlock ,doorNumber},answerPoints };
		//30m+ 1h 20 m +15m=2H 5M
	}
};

标签:LC,int,749,isInfected,vector,bfsQueue,nextJ,size,隔离
From: https://www.cnblogs.com/zwf4/p/18304689

相关文章

  • 树上问题/简单算法 LCA【最近公共祖先】
    概念引入最近公共祖先简称\(LCA\)(LowestCommonAncestor)。两个节点的最近公共祖先,就是这两个点的公共祖先里面,离根最远的那个。在下面的说明中,我们设两个节点分别为\(x\),\(y\),节点\(x\),\(y\)的深度分别表示为\(dep_x\),\(dep_y\),将树称为\(T\)算法详解:朴素算法:......
  • mipi LCD 的CLK时钟频率与显示分辨率及帧率的关系
    我们先来看一个公式:Mipiclock=[(width+hsync+hfp+hbp)x(height+vsync+vfp+vbp)]x(bus_width)xfps/(lane_num)/2即mipi屏的传输时钟频率(CLKN,CLKP)等于(屏幕分辨率宽width+hsync+hfp+hbp)x(屏幕分辨率高height+vsync+vfp+vbp)x(RGB显示数据宽度)x帧率/(lane_num)/......
  • Modbus转Ethernet IP网关模块与汇川PLC通讯在网关配置软件中的配置
    通过Modbus转Ethernet/IP网关模块(XD-MDEP100),可以实现不同协议之间的互连,从而使得设备之间的数据交换更加便捷高效。网关做为ETHERNET/IP网络的从站,可以连接AB(罗克韦尔)、欧姆龙、基恩士、CODESYS、汇川等品牌的PLC。在实际案例中,汇川PLC作为控制系统部件与Modbus转Ethernet/IP......
  • SQLCoder部署和应用
    主页个人微信公众号:密码应用技术实战个人博客园首页:https://www.cnblogs.com/informatics/SQLCoder简介SQLCoder是一个用于生成SQL语句的工具,可以通过输入自然语言描述的需求,生成对应的SQL语句。SQLCoder支持连接数据库,对生成的SQL语句可以直接自动执行,并以图表的形式展示结......
  • 虚树复习 & O(1) 查询 LCA
    放假是不可能做题的。那就写总结把。虚树问题的情境涉及多次树上询问,每次指定一些点,让你计算。此类问题需要我们在线地找到尽可能少的【关键点】进行计算,最好和给的点级别一样。虚树的思想就是这个过程。二次排序一个关键直觉:【指定点】两两的LCA一定是【关键点】。并且......
  • 【攻防技术系列】shellcode初始
    虚拟机环境搭建【Kali】:192.168.10.131【win】:192.168.10.1shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。但是想要更充分理解什么是shellcode,我们得先了解下可执行程序和shellcode都是怎么运行的。简单来说......
  • [极客大挑战 2020]Roamphp1-Welcome 1
    前端代码审计,信息收集,sha1绕过进来之后发现什么都没有,什么东西都找不到,扫后台也没东西,可以看到在请求头中有异常尝试切换get传参为post传参爆出了源码<?phperror_reporting(0);if($_SERVER['REQUEST_METHOD']!=='POST'){header("HTTP/1.1405MethodNotAllowed")......
  • C#、PLC中数据类型学习及汇总
    前言 注:不同语言部分类型定义和取值范围有所不同。编程语言如C#、C++等数据类型丰富多样,而PLC中的数据类型一般比较简单,这里汇总一下常用的数据类型,以便以后查阅。自己一个个手敲学习总结,如果有错望留言指正,如觉得还有用,请点赞收藏。目录前言1、C#中常用的值类型:可以直接......
  • 毕业设计 基于机器视觉的PCB焊接缺陷检测系统(Halcon+C#)
    毕业设计基于机器视觉的PCB焊接缺陷检测系统一、功能需求检测PCB板的焊接缺陷:漏焊、虚焊等二、开发环境1、Halcon2、C#三、运行效果处理图片:运行视频:毕业设计基于机器视觉的PCB焊接缺陷检测系统毕业设计资料(C#软件源码+Halcon算法源码+开题报告+毕业设计+......
  • Tool-Cross-compilation-Toolchain-ARM-Linaro
    Tool-Cross-compilation-Toolchain-ARM-LinaroUbuntu上基于Arm的交叉编译工具链。引用:arm生态发展与交叉编译链选择-知乎arm-none-linux-gnueabi-gcc:是Codesourcery公司(目前已经被Mentor收购)基于GCC推出的的ARM交叉编译工具。可用于交叉编译ARM(32位)系统中所有环节的代码,包......