【二维差分】2132. 用邮票贴满网格图

本文涉及知识点

二维差分

LeetCode2132. 用邮票贴满网格图

给你一个 m x n 的二进制矩阵 grid ,每个格子要么为 0 (空)要么为 1 (被占据)。
给你邮票的尺寸为 stampHeight x stampWidth 。我们想将邮票贴进二进制矩阵中,且满足以下 限制 和 要求 :
覆盖所有 空 格子。
不覆盖任何 被占据 的格子。
我们可以放入任意数目的邮票。
邮票可以相互有 重叠 部分。
邮票不允许 旋转 。
邮票必须完全在矩阵 内 。
如果在满足上述要求的前提下,可以放入邮票,请返回 true ,否则返回 false 。
示例 1:

输入:grid = [[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0]], stampHeight = 4, stampWidth = 3
输出:true
解释:我们放入两个有重叠部分的邮票(图中标号为 1 和 2),它们能覆盖所有与空格子。
示例 2:

输入:grid = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]], stampHeight = 2, stampWidth = 2
输出:false
解释:没办法放入邮票覆盖所有的空格子,且邮票不超出网格图以外。

提示:
m == grid.length
n == grid[r].length
1 <= m, n <= 105
1 <= m * n <= 2 * 105
grid[r][c] 要么是 0 ,要么是 1 。
1 <= stampHeight, stampWidth <= 105

二维差分

邮票无限,且可以相互覆盖,能成为邮票左上角的位置,都放一张。
邮票的左上角能否放到(r,c),则称(r,c)能否放置邮票。
两轮二维差分:
一,vDiff1记录,那些位置可以放邮票。
二,vDiff2记录那些位置已经放置了邮票或被占据。
具体:
一,如果(r,c)被占据,则左上角(r-stampHeight+1,c - stampWidth+1),右下角为(r,c)的矩形无法放置邮票。左上角不能为负数。
二,ans1 = vDif1的结果。
三,从0到大枚举r,直到r+stampHeight<=m不成立。从0到大枚举c,直到c+stampWidth<=n不成立。
,如果vDiff[r][c]等于0,则放置邮票到vDiff2。
四,r = 0 to m-1 ,c = 0 to n-1,如果grid[r][c]=1,则vDiff.set(r,c,r+1,c+1)
五,ans2 = vDiff2的结果。
六,r = 0 to m-1 ,c = 0 to n-1,如果res2[r][c]等于0,返回fasle。
七,return true;
一四可以合并。

代码

核心代码

template<class T = int >
class CDiff2
{
public:
	CDiff2(int r, int c) :m_iR(r), m_iC(c) {
		m_vDiff.assign(m_iR, vector<T>(m_iC));
	}
	void Set(int r1, int c1, int r2Exinc, int c2Exinc, int iAdd) {
		m_vDiff[r1][c1] += iAdd;
		m_vDiff[r2Exinc][c2Exinc] += iAdd;
		m_vDiff[r1][c2Exinc] -= iAdd;
		m_vDiff[r2Exinc][c1] -= iAdd;
	}
	vector<vector<T>> Ans()const {
		vector<vector<T>> res(m_iR, vector<T>(m_iC));
		vector<T> vCols(m_iC);
		for (int r = 0; r < m_iR; r++) {
			T iSum = 0;
			for (int c = 0; c < m_iC; c++) {
				vCols[c] += m_vDiff[r][c];
				iSum += vCols[c];
				res[r][c] = iSum;
			}
		}
		return res;
	}

	const int m_iR, m_iC;
protected:
	vector<vector<T>> m_vDiff;
};

class Solution {
public:
	bool possibleToStamp(vector<vector<int>>& grid, int stampHeight, int stampWidth) {
		const int R = grid.size();
		const int C = grid[0].size();
		CDiff2 diff1(R + 1, C + 1), diff2(R + 1, C + 1);
		for (int r = 0; r < R; r++) {
			for (int c = 0; c < C; c++) {
				if (0 == grid[r][c]) { continue; }
				diff1.Set(max(0, r - stampHeight + 1), max(0, c - stampWidth + 1), r + 1, c + 1, 1);
				diff2.Set(r, c, r + 1, c + 1, 1);				
			}
		}
		auto ans1 = diff1.Ans();
		for (int r = 0; r + stampHeight <= R; r++) {
			for (int c = 0; c + stampWidth <= C; c++) {
				if (0 == ans1[r][c]) {
					diff2.Set(r, c, r + stampHeight, c + stampWidth, 1);
				}
			}
		}
		auto ans2 = diff2.Ans();
		for (int r = 0; r < R; r++) {
			for (int c = 0; c < C; c++) {
				if (0==ans2[r][c] ) { return false; }
			}
		}
		return true;
	}
};

单元测试

template<class T1,class T2>
void AssertEx(const T1& t1, const T2& t2)
{
	Assert::AreEqual(t1 , t2);
}

template<class T>
void AssertEx(const vector<T>& v1, const vector<T>& v2)
{
	Assert::AreEqual(v1.size(), v2.size());	
	for (int i = 0; i < v1.size(); i++)
	{
		Assert::AreEqual(v1[i], v2[i]);
	}
}

template<class T>
void AssertV2(vector<vector<T>> vv1, vector<vector<T>> vv2)
{
	sort(vv1.begin(), vv1.end());
	sort(vv2.begin(), vv2.end());
	Assert::AreEqual(vv1.size(), vv2.size());
	for (int i = 0; i < vv1.size(); i++)
	{
		AssertEx(vv1[i], vv2[i]);
	}
}

namespace UnitTest
{
	vector<vector<int>> grid;
	int stampHeight,  stampWidth;
	TEST_CLASS(UnitTest)
	{
	public:
		TEST_METHOD(TestMethod0)
		{
			grid = { {1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0} }, stampHeight = 4, stampWidth = 3;
			auto res = Solution().possibleToStamp(grid, stampHeight, stampWidth);
			AssertEx( true, res);
		}
		TEST_METHOD(TestMethod1)
		{
			grid = { {1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1} }, stampHeight = 2, stampWidth = 2;
			auto res = Solution().possibleToStamp(grid, stampHeight, stampWidth);
			AssertEx(false, res);
		}
	
		
	};
}

扩展阅读

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关推荐

我想对大家说的话
《喜缺全书算法册》以原理、正确性证明、总结为主。
按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/716113.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

租房项目之并发缺失数据问题

前奏&#xff1a;本项目是一个基于django的租房信息获取项目。本次博客牵扯到两个版本&#xff0c;集中式分布以及分布式部署&#xff08;两个版本的ui不同&#xff0c;集中式用的是老版ui&#xff0c;分布式使用的是新版ui&#xff09;&#xff1b; 项目链接&#xff1a;http…

【C++提高编程-09】----C++ STL之常用排序算法

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

04 翼型和机翼、尾翼几何选择

04 翼型和机翼、尾翼几何选择 4 -1 引言4-2 翼型的选择4-2-1 翼型的几何4-2-2 翼型的升力和阻力4-2-3 翼型选择与设计4-2-4 设计升力系数4-2-5 失速4-2-6 翼型厚度比4-2-7 关于翼型其他方面的考虑 4-3 机翼几何外形4-3-1 展弦比4-2-3 机翼后掠角4-3-3 机翼稍根比4-3-4 机翼扭转…

echarts学习:使用dataset管理数据

前言 在我们公司的组件库中有许多echarts图表相关的组件&#xff0c;这些组件在使用时&#xff0c;只需将图表数据以特定的格式传入组件中&#xff0c;十分方便。因此当我得知echarts 可以使用dataset集中管理数据时&#xff0c;我就决定自己一定要搞懂它&#xff0c;于是在最…

第2章 Rust初体验6/8:Option枚举及其变体:能避免空指针异常问题:猜骰子冷热游戏

讲动人的故事,写懂人的代码 2.6 故事4: 一直让玩家不断猜 我们全班要一起用三种语言来写第4个故事啦。这可能是我们所有故事中最复杂的一个了。不过别担心,贾克强已经把这个故事的需求都用投影仪展示出来了。 程序会提示玩家猜两个骰子的点数之和。如果玩家第一次输入点数之…

C#反射机制介绍

文章目录 简介一、什么是反射二、反射的用途三、反射用到的命名空间及主要类四、Type类五、Assembly类六、使用反射实现上面的程序七、反射的优缺点 简介 这篇文章介绍了C#的反射机制&#xff0c;文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值&a…

DAY5-力扣刷题

1.两两交换链表中的节点 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换…

Kubernetes新手必看:快速生成YAML清单的终极指南!

在这篇文章中&#xff0c;你将学习到几种快速创建Kubernetes YAML清单的方法&#xff0c;这些方法可以帮助你在Kubernetes中测试和部署应用程序。这些技巧同样适用于Kubernetes认证考试。 在使用Kubernetes时&#xff0c;我们经常需要搜索Kubernetes YAML文件以便部署测试Pod、…

编写一个简单的Mybatis插件

1.编写一个类&#xff0c;实现Intercepter这个接口 2.完成这个类的方法&#xff0c;并通过注解Intercepts来告诉Mybatis这个插件拦截哪个类和哪个方法 3.在Mybatis的全局配置文件里注册这个插件&#xff0c;让插件生效 4.玩一个实际功能的插件

家庭智能助手:Kompas AI引领家居智能化新纪元

一、引言 在数字化浪潮的推动下&#xff0c;现代家庭生活正迅速向智能化转型。从简单的自动化设备到复杂的智能家居系统&#xff0c;智能技术正悄无声息地改变我们的日常生活。Kompas AI作为一款前沿的家庭智能助手&#xff0c;不仅预示着家庭生活的未来趋势&#xff0c;更以其…

每日一练:攻防世界:ewm

这道题我尝试了使用montagegaps解题&#xff0c;但是没有解出来&#xff0c;图片数量不是很多&#xff0c;可以尝试用PS直接拼图&#xff0c;但是这样学不到东西&#xff0c;我也就没尝试&#xff0c;直接看的官方WP 这段代码应该是改变工作目录到small&#xff0c;并且变量当…

Sping源码(九)—— Bean的初始化(非懒加载)— Bean的创建方式(自定义BeanPostProcessor)

序言 之前文章有介绍采用FactoryBean的方式创建对象&#xff0c;以及使用反射创建对象。 这篇文章继续介绍Spring中创建Bean的形式之一——自定义BeanPostProcessor。 之前在介绍BeanPostProcessor的文章中有提到&#xff0c;BeanPostProcessor接口的实现中有一个Instantiatio…

Tensorflow-GPU工具包了解和详细安装方法

目录 基础知识信息了解 显卡算力 CUDA兼容 Tensorflow gpu安装 CUDA/cuDNN匹配和下载 查看Conda driver的版本 下载CUDA工具包 查看对应cuDNN版本 下载cuDNN加速库 CUDA/cuDNN安装 CUDA安装方法 cuDNN加速库安装 配置CUDA/cuDNN环境变量 配置环境变量 核验是否安…

【乐吾乐2D可视化组态编辑器】导航

支持点击图元&#xff0c;切换画面或跳转链接。 乐吾乐2D可视化组态编辑器地址&#xff1a;https://2d.le5le.com/ 切换画面 1. 添加事件 2. 设置事件行为 事件行为"发送消息"&#xff0c;消息名选择"导航"。 3. 配置消息参数 消息参数&#xff0c;…

图像的对比度和亮度

目标 访问像素值用0来初始化矩阵cv::saturate_cast像素转换提高一张图像的亮度 原理 图像处理 图像变换可以被视作两个步骤&#xff1a; 点操纵&#xff08;像素转换&#xff09;相邻区域转换&#xff08;以面积为基础&#xff09; 像素转换 在这种图像处理的转换过程中…

操作系统 - 进程的控制(创建与终止)

进程控制 文章目录 进程控制进程创建进程的终止wait()和waitpd()僵尸进程孤儿进程 进程创建 程序在执行的过程中&#xff0c;可能会创建多个进程&#xff0c;创建进程称为父进程&#xff0c;新的进程称为子进程&#xff0c;每个新的进程也可以创建其他进程&#xff0c;从而形成…

LinkedHashMap详解

目录 LinkedHashMap详解1、LinkedHashMap的继承体系2、LinkedHashMap的特性介绍和代码示例①、特性②、适用场景使用LinkedHashMap 实现最简单的 LRU缓存 3、LinkedHashMap的构造函数4、LinkedHashMap是如何存储元素的&#xff0c;底层数据结构是什么&#xff1f;LinkedHashMap…

功能强大的多功能文档转换工具Neevia Document Converter Pro 7.5.0.241

Neevia Document Converter Pro是一款功能强大的Windows软件,旨在将文档转换为各种格式,包括PDF、TIFF、JPEG和许多其他格式。该程序专为在企业环境中使用而设计,提供文档转换和处理过程的自动化,这使其成为处理大量文档的组织的***工具。 Neevia Document Converter Pro的…

基于Quartus Prime18.1的安装与FPGA的基础仿真(联合Modelsim)教程

Quartus是一种美国科技公司Intel&#xff08;英特尔&#xff09;公司开发的FPGA&#xff08;现场可编辑门阵列&#xff09;设计编译软件&#xff0c;用作设计、仿真、综合和布局、支持多种编程语言&#xff0c;包括VHDL、Verilog等&#xff0c;并具有丰富的功能和工具库&#x…

游戏中插入音效

一、背景音乐 准备&#xff1a;素材音乐 方法&#xff1a; 1、方法1&#xff1a; (1) 将背景音乐 bgAudio 拖放到Hierarchy面板 (2) 选中 bgAudio&#xff0c;勾选开始运行就播放、循环播放。调节音量&#xff08;volume) 2、方法2&#xff1a; (1) Create Empty&#x…