题解 # 二维矩阵最大矩形问题#

news2024/10/1 19:33:18

题目:

小明有一张N*M的方格纸,且部分小方格中涂了颜色,部分小方格还是空白。


给出N (2<Ns30)和M(2sMs30)的值,及每个小方格的状态((被涂了颜色小方格用数字1表示,空白小方格用数字0表示);

请帮助小明找出最大的矩形空白区域,并输出该矩形空白区域由多少个小方格组成。


例如:N=4, M=5,4*5的方格纸中每个小方格的状态如下图:

 

最大的空日区域由6个小方格组成(红色框区域)。

思路:

暴力穷举法:

1、将每一个方格的下边0的个数、右边0的个数进行统计

2、在由下边0的个数和右边0的个数以及该方格围城的矩形中,筛选出值是1的方格,进行0个数的回退。

3、将每一个方格的下标、下边0的个数,右边0的个数进行保存,最后再求最大的面积

4、如果这个方格里面是1则,从该方格出发是不能构成数据全部为0的矩形的,行刺可以直接将该方格的下边0和右边0的个数设置为0,排除即可。

5、最后查找 下边0的个数 >= 1   同时   右边0的个数也 >= 1的找到面积最大的矩形。

代码:

#include<stdio.h>
#define N 4
#define M 5 
#define NUM (N*M)

int main()
{
	int arr[N][M] = {
		{1,1,0,0,0},
		{1,0,1,0,0},
		{0,0,0,1,1},
		{0,0,0,1,0},
	};
	
	//  本例采用数组存储,因为有多个数组因此采用 二维数组方式
	int posArr[NUM][4]={0};
	
	// 先获取每一个数据
	// arr数据的行下标 
	int i;
	// arr数据的列下标 
	int j;
	
	printf("原始数组信息:\n");
	for(i=0;i<N;i++)
	{
		for(j=0;j<M;j++)
		{
			printf("%d ",arr[i][j]); 
		}
		printf("\n");
	}
	
	// 查找下边0的临时下标 
	int k;
	// 查找右边0的临时下标 
	int t;
	
	// 下边0的个数 
	int bottom = 0;
	// 右边0的个数 
	int right = 0;
	
	// 存放最大矩形信息的下标。
	int maxI;
	// 最大矩形的面积 
	int maxArea;
	
	for(i=0;i<N;i++)
	{
		for(j=0;j<M;j++)
		{				
			// 如果该数据是1,不能构成以这个点为定点的矩形,则不需要向下和向右统计0的个数了 
			if(arr[i][j] != 0)
			{
				posArr[i*M+j][0] = i; 
				posArr[i*M+j][1] = j; 
				posArr[i*M+j][2] = 0; 
				posArr[i*M+j][3] = 0; 
				continue;
			}
			
			// 如果该数据是0,可能构成 以这个点为定点的矩形
			bottom = 0;
			right = 0;
			// 查找下边0的个数;
			for(k=j+1;k<M;k++)
			{
				if(arr[i][k] == 0)
				{
					right++;
				}
				else
				{
					break;
				}
			} 
			
			// 向右查找0的个数
			for(t=i+1;t<N;t++)
			{
				if(arr[t][j] == 0)
				{
					bottom++;
				}
				else
				{
					break;
				}
			} 
			
			// 以行为准查找1,将不和要求的矩形排除掉,当前位置为i 和 j		
			for(k=i+1;k<=i + bottom;k++)
			{
				for(t=j;t<=j + right;t++)
				{
					if(arr[k][t] == 1)
					{
						if(k > t)
						{
							bottom -= 1;
						}
						else if(k < t)
						{
							right -= 1;
						}
						else
						{
							bottom -= 1;
							right  -= 1;
						}
					}
				}
			} 			
				 
			posArr[i*M+j][0] = i; 
			posArr[i*M+j][1] = j; 
			posArr[i*M+j][2] = bottom; 
			posArr[i*M+j][3] = right; 
		}	
	} 	

	// 访问数据
	maxI = 0;
	maxArea=0; 
	int tempArea = 0;
	for(i=0;i<NUM;i++)
	{
		if(posArr[i][2] == 0 && posArr[i][3] != 0)
		{
			tempArea = 1 * posArr[i][3];
		}
		
		if(posArr[i][2] != 0 && posArr[i][3] == 0)
		{
			tempArea = 1 * posArr[i][2];
		}
		
		if(posArr[i][2] == 0 && posArr[i][3] == 0)
		{
			tempArea = 1;
		}
		
		if(posArr[i][2] != 0 && posArr[i][3] != 0)
		{
			tempArea = (posArr[i][2]+1) * (posArr[i][3]+1);
		}
		
		if(maxArea < tempArea)
		{
			maxI = i;
			maxArea = tempArea;
		}			
	} 
	
	printf("最大矩形的信息:\n");
	printf("左上角的坐标点为:第%d行第%d列\n",posArr[maxI][0],posArr[maxI][1]);
	printf("宽:%d,高%d\n",posArr[maxI][3]+1,posArr[maxI][2]+1);
	printf("面积为:%d\n",(posArr[maxI][3]+1)*(posArr[maxI][2]+1));
	 
	return 0;
}

效果演示:

 

 

拓展:

求正方形该代码也使用,查找 下方0个数和右边0个数一样的组合即可。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java泛型学习篇(一)

java泛型学习篇(一) 1 学习泛型前的传统思路 1.1 遍历集合中元素的方法 1.1.1 思路 ①用foreach进行遍历 ②把每个Object对象强转成所需类型 ③打印其值1.1.2 示例代码 import java.util.ArrayList; public class Generic01 {public static void main(String[] args) {lon…

机器学习:基于主成分分析(PCA)对数据降维

机器学习&#xff1a;基于主成分分析&#xff08;PCA&#xff09;对数据降维 作者&#xff1a;AOAIYI 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;AOAIYI首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可…

JavaWeb--HTTP

HTTP1 简介2 请求数据格式2.1 格式介绍3 响应数据格式3.1 格式介绍3.2 响应状态码3.2.1状态码大类3.2.2常见的响应状态码3.3 自定义服务器目标&#xff1a; 理解HTTP协议和HTTP请求与响应数据的格式 1 简介 HTTP概念 HyperText Transfer Protocol&#xff0c;超文本传输协议&a…

造成android UI卡顿的原因及解决方法

Android 系统每隔 16ms 会发出 VSYNC 信号重绘界面(Activity)。之所以是 16ms&#xff0c;是因为 Android 设定的刷新率是 60FPS(Frame Per Second)&#xff0c;也就是每秒 60 帧的刷新率&#xff0c;约合 16ms 刷新一次。如果UI线程的执行时间超过16ms&#xff0c;则会产生丢帧…

JavaSE08-运算符

文章目录一、算术运算符1.字符参与运算2.字符串参与 运算二、赋值运算符三、自增自减运算符四、比较运算符五、逻辑运算符六、三元运算符算术运算符、赋值运算符、自增自减运算符、比较运算符、逻辑运算符、三元运算符一、算术运算符 1.字符参与运算 char类型参与算术运算&…

Jmeter使用教程

目录一&#xff0c;简介二&#xff0c;Jmeter安装1&#xff0c;下载2&#xff0c;安装三&#xff0c;创建测试1&#xff0c;创建线程组2&#xff0c;创建HTTP请求默认值3&#xff0c;创建HTTP请求4&#xff0c;添加HTTP请求头5&#xff0c;添加断言6&#xff0c;添加查看结果树…

BoostSearcher搜索引擎项目

BoostSearcher搜索引擎项目 1.BoostSearcher这个项目是什么&#xff1f; 答&#xff1a;一个为Boost文档建立索引的站内搜索引擎&#xff0c;简单的说就是一个类似于csdn站内文档搜索框。 项目展示&#xff1a; gitee:https://gitee.com/zxlfx/boost-search-engine-project …

二叉树——堆

一&#xff0c;树的概念及结构 1.树 4.结点的度&#xff1a;一个节点含有子树的个数称为该结点的度&#xff1b;如&#xff1a;A 的度为6. 5.叶节点或终端节点&#xff1a;度为0的节点称为叶节点&#xff1b;如&#xff1a;B 6.非终端结点或分支节点&#xff1a;度部位0的结…

【华为OD机试模拟题】用 C++ 实现 - 吃火锅(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

【华为OD机试模拟题】用 C++ 实现 - 分积木(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

基于博客系统的测试用例

登陆界面博客预览页博客详情页博客编辑页

每日一题——L1-085 试试手气(15)

L1-085 试试手气 我们知道一个骰子有 6 个面&#xff0c;分别刻了 1 到 6 个点。下面给你 6 个骰子的初始状态&#xff0c;即它们朝上一面的点数&#xff0c;让你一把抓起摇出另一套结果。假设你摇骰子的手段特别精妙&#xff0c;每次摇出的结果都满足以下两个条件&#xff1a;…

【Java8】

1、接口中默认方法修饰为普通方法 在jdk8之前&#xff0c;interface之中可以定义变量和方法&#xff0c;变量必须是public、static、final的&#xff0c;方法必须是public、abstract的&#xff0c;由于这些修饰符都是默认的。 接口定义方法: public抽象方法需要子类实现 接口定…

TCP报文详解

目录 &#x1f407;今日良言:但尽全力,且让心安 &#x1f43c;一、TCP协议特点 &#x1f433;二、TCP协议段格式 &#x1f42f;三、TCP的10个核心机制 &#x1f41d;四、三次握手和四次挥手 &#x1f407;今日良言:但尽全力,且让心安 &#x1f43c;一、TCP协议特点 TCP :Tr…

OAuth 2.0 认证和攻击面

0x00 前提 最近在测试公司的 oauth 认证方面的问题&#xff0c;要再去熟悉一下这块&#xff0c;所以把这块写一下。 0x01 OAuth2.0 概念 OAuth是一个关于授权&#xff08;authorization&#xff09;的开放网络标准&#xff0c;目前是最常见最通用的一个授权协议。 什么地方…

uni-app:获取当前经纬度解决方案+如何布置全局组件

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 一.布置全局组件 在我们开发的过程中&#xff0c;会碰到一个现象&#xff0c;就是在页面里面引入组件&#xff0c;总算要写import&#xff0c;components才能引用&#xff0c;这里给大家分享我们的一个…

JavaWeb--Tomcat

Tomcat1 简介1.1 什么是Web服务器2 基本使用2.1 下载2.2 安装2.3 卸载2.4 启动2.5 关闭2.6 配置2.7 部署3 Maven创建Web项目3.1 Web项目结构3.2 创建Maven Web项目4 IDEA使用Tomcat4.1 集成本地Tomcat4.2 Tomcat Maven插件目标&#xff1a; 掌握Tomcat的使用掌握在IDEA中使用To…

CMake模块的使用和自定义模块

CMake模块的使用和自定义模块一、前言二、使用Find模块2.1、准备工作2.2、添加头文件路径和库文件2.3、< name >_FOUND 来控制工程特性三、编写自定义的Find模块3.1、 准备工作3.2、cmake 模块3.3、使用自定义的FindHELLO 模块构建工程3.4、如果没有找到hello library四、…

备战金三银四,熬夜半个月汇集大厂 Java 岗 1600 页面试真题

如果你不停地加班。却很少冒险&#xff0c;也很少学习&#xff0c;那你极大可能会陷入到内卷中。 为什么这么说呢&#xff1f;我们先来捋清楚「内卷」的概念&#xff1a; 「内卷化」简而言之就是&#xff1a;日复一日&#xff0c;越混越掉坑里。 所谓内卷化&#xff0c;指一种…

CHAPTER 2 Web Server - nginx 功能示例

nginx功能示例2.1 Nginx反向代理-示例1. 配置nginx.conf2. 配置访问机器的hosts3. 访问网址4. 遗留问题2.2 Nginx负载均衡-详解及示例2.2.1 负载均衡配置参数简介1. upstream模块简介2. 负载均衡算法简介2.2.2 示例演示1. 修改配置文件2. 示例效果2.3 Nginx动静分离-示例1. 修改…