最大子矩阵(蓝桥杯)暴搜 JAVA

news2025/1/18 6:29:57

题目描述:

小明有一个大小为N×M的矩阵,可以理解为一个N行M列的二维数组。 我们定义一个矩阵m 的稳定度f(m)
为f(m)=max(m)-min(m)。 其中max(m)表示矩阵m中的最大值,min(m) 表示矩阵m 中的最小值。
现在小明想要从这个矩阵中找到一个稳定度不大于limit 的子矩阵; 同时他还希望这个子矩阵的面积越大越好(面积可以理解为矩阵中元素个数)。

子矩阵定义如下:

从原矩阵中选择一组连续的行和一组连续的列,这些行列交点上的元素组成的矩阵即为一个子矩阵。

输入格式:

第一行输入两个整数N,M,表示矩阵的大小。 接下来N 行,每行输入M 个整数,表示这个矩阵。 最后一行输入一个整数limit,表示限制。

在这里插入图片描述

对于所有评测用例,0≤矩阵元素值, limit≤10^5。

输出格式:

输出一个整数,分别表示小明选择的子矩阵的最大面积。

输入样例:

3 4
2 0 7 9
0 6 9 7
8 4 6 4
8

输出样例:

6

数据范围与提示

满足稳定度不大于8 的且面积最大的子矩阵总共有三个,他们的面积都是6(粗体表示子矩阵元素):

2 0 7 9
0 6 9 7
8 4 6 4

2 0 7 9
0 6 9 7
8 4 6 4

2 0 7 9
0 6 9 7
8 4 6 4

解题思路:

本题采用dfs + 回溯的思想来解决,也就是朴素的暴搜。

若要利用好深搜索得先搞清以下问题:

1.应先明确遍历的起点:
数组中每个元素都可以是起点,这样能无死角地找到所有符合条件的子矩阵。 所以我们要对数组内每个点都进行遍历,不断更新面积最大值。

2.如何知道我们遍历过的符合条件的区域是一个矩阵?(这是我们更新子矩阵面积所必需要知道的。)
在这里插入图片描述
对号”部分是是我们遍历过的区域。

很明显这不是一个矩阵,但是若我们知道遍历过的点的横坐标范围,和纵坐标的范围,问题就解决了。
在这里插入图片描述

知道范围后,在这个范围内(即蓝色区域内)遍历一下看看是不是所有点都被遍历过,是则满足子矩阵,否则不满足,这需要单独构建一个布尔数组,和一个判断是否为矩阵的函数。

3.遍历规则:
我们知道 深度优先遍历是一个路径,而我们想要的是子矩阵。
即如果我么们给的限制条件只是在数组区间内遍历,那么它就会在这个区间乱窜。所以我么们需要施加新条件来限制它的遍历轨迹,确保以遍历子矩阵为优先。
即,如果当前遍历路径不是子矩阵的话,我们就将当前所在矩阵区域遍历满。如果当前遍历区域是一个子矩阵的话,我们就扩大边界,试着去得到面积更大的符合条件的子矩阵。

4.遍历过程的模拟:

理清思路后我们可以模拟一下遍历过程,以确保万无一失。想学好 dfs 会模拟自己写的程序是必不可少的。

以题目中例1的遍历为例以下是我的模拟过程,可以助于理解:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

理论成立代码如下:

import java.util.Scanner;

public class Main {
    public static int n = 0;
    public static int m = 0;
	public static void main(String[] args){
       Scanner sc = new Scanner(System.in);
       n = sc.nextInt();
       m = sc.nextInt();
       int a[][] = new int[n + 10][m + 10];//储存数组
       visit = new boolean[n][m];
       for(int i = 0; i < n; i ++)
    	   for(int j = 0; j < m; j ++) a[i][j] = sc.nextInt();
       
       f = sc.nextInt();
       
       for(int i = 0; i < n; i ++)
    	   for(int j = 0; j < m; j ++) {
    		   mini = i;
    		   minj = j;
    		   maxi = i;
    		   maxj = j; 
    		   sunmatrix = 1;
    		   minvalue = a[i][j];
    		   maxvalue = a[i][j];	   // 初始化
    		   
    		   visit[i][j] = true;//标记
    		   dfs(a, i, j);
    		   visit[i][j] = false;//回溯
    		   
    		   maxsmatrix = Math.max(sunmatrix, maxsmatrix);//更新
    		   
    	   }
       
       System.out.print(maxsmatrix);//最终结果
       
}
   public static boolean visit[][];//储存路径
   public static int mini = 0;
   public static int maxi = 0;
   public static int minj = 0;
   public static int maxj = 0;//储存矩阵范围
   
   public static int f = 0;//储存题目要求稳定度
  
   public static int minvalue = 0;
   public static int maxvalue = 0;//储存遍历过的路径最大值与最小值
   
   public static int sunmatrix = 0;//储存每次遍历最大面积
   public static int maxsmatrix = 0; // 储存最终答案
   
   public static void updatemx(int i, int j) {//更新遍历的矩阵范围
	   mini = Math.min(mini, i);
	   minj = Math.min(minj, j);
	   maxi = Math.max(maxi, i);
	   maxj = Math.max(maxj, j);
   }
   
   public static int F(int value) {//判断矩阵稳定度
	   minvalue = Math.min(minvalue, value);
	   maxvalue = Math.max(maxvalue, value);//更新
	   
	   return maxvalue - minvalue;
   }
   
   public static void dfs(int a[][], int i, int j) {
	   int bfminvalue = minvalue;
	   int bfmaxvalue = maxvalue;
	   if(ifmatrix() && F(a[i][j]) <= f)//最重要的事情最先做,如果路径满足矩阵且新点符合条件,更新子矩阵面积
		   sunmatrix = Math.max(sunmatrix, (maxi - mini + 1) * (maxj - minj + 1));//新子矩阵面积计算过程
	   minvalue = bfminvalue;
	   maxvalue = bfmaxvalue;//回溯
	   
	   int fxx = 0, fyy = 0;
	   int fx[] = {-1, 1, 0, 0};
	   int fy[] = {0, 0, -1, 1};//上下左右
	   
	   for(int k = 0; k < 4; k ++) {
		   fxx = i + fx[k];
		   fyy = j + fy[k];
		   
		   int bfmini = mini;
		   int bfmaxi = maxi;
		   int bfminj = minj;
		   int bfmaxj = maxj; 
		   bfminvalue = minvalue;
		   bfmaxvalue = maxvalue;//存着用于回溯
		   
		   if(ifmatrix()) {//是矩阵,扩张
			   if(fxx >= 0 && fxx < n && fyy >= 0 && fyy < m && visit[fxx][fyy] != true && F(a[fxx][fyy]) <= f) {
				   visit[fxx][fyy] = true;//标记来过
				   updatemx(fxx, fyy);//更新边界
				   dfs(a, fxx, fyy);
				   visit[fxx][fyy] = false;
			   }
		   }
		   else {//否者把目前范围矩阵遍历完
			   if(fxx >= mini && fxx <= maxi && fyy >= minj && fyy <= maxj && visit[fxx][fyy] != true && F(a[fxx][fyy]) <= f) {
				   visit[fxx][fyy] = true;
				   updatemx(fxx, fyy);
				   dfs(a, fxx, fyy);
				   visit[fxx][fyy] = false;
			   }
		   }
		   minvalue = bfminvalue;
		   maxvalue = bfmaxvalue;//回溯
		   mini = bfmini;
		   minj = bfminj;
		   maxi = bfmaxi;
		   maxj = bfmaxj;
	   }
	   
   }
   
   public static boolean ifmatrix() {//判断此路径是否是矩阵
	   for(int i = mini; i <= maxi; i ++)
		   for(int j = minj; j <= maxj; j ++)
			   if(visit[i][j] != true)  return false;
	   return true;
   }
   
}

此代码虽然长,但只要弄懂上述问题,逐一解决,条理还是很清晰的,本代码在官方平台上测试能搞到九成分数,剩下的两个测试点是超时了。能对的都对了。想拿满分的话可以看看别的大佬写的别的方法,对于我来说如果真让我在赛场上遇到这道题的话,我能用这个朴素爆搜混点分就很满足的,打死也想不出其他方法了。
在这里插入图片描述

此代码能优化的我也优化了,如果有些地方还可以优化的话,欢迎各大佬指点。

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

2023-03-09干活小计

强化学习&#xff1a; 强化学习用智能体&#xff08;agent&#xff09;这个概念来表示做决策的机器。 感知、决策和奖励 感知。智能体在…

【ECCV 2022】76小时动捕,最大规模数字人多模态数据集开源

随着元宇宙的火爆以及数字人建模技术的商业化&#xff0c;AI 数字人驱动算法&#xff0c;作为数字人动画技术链的下一关键环节&#xff0c;获得了学界和工业界越来越广泛的兴趣和关注。其中谈话动作生成 &#xff08;由声音等控制信号生成肢体和手部动作&#xff09;由于可以降…

ChatGPT正当时,让我们一起深耕智能内容生成和智能内容增强领域

ChatGPT以其强大的信息整合和对话能力惊艳了全球&#xff0c;在自然语言处理上面表现出了惊人的能力。很多人都预测 2023 年将是 AI 生成之年&#xff0c;也许我们将迎来继农业革命、工业革命以来的第三种通用技术的普及。 信必优长期专注于人工智能领域&#xff0c;拥有产品研…

力扣-求关注者的数量

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1729. 求关注者的数量二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.正确…

Linux下创建ln链接文件

1.linux重定向命令 >ls > a.txt将ls显示的结果 输出到文件中1.echo "hello world"2.往终端上输出 字符串"hello world"echo "hello " >c.txt 将"hello "字符串 输出到文件中&#xff08;覆盖&#xff09;echo "world&qu…

MFC 简单使用事件

功能三个按钮,一个静态框,默认值是0,增加减少按钮和退出按钮.增加减少按钮显示在静态框中.退出按钮退出软件.实验事件思路新建三个事件,add事件sub事件quit事件,一个按钮触发一个事件,静态框新建一个线程接受事件做出对应的改变.UI添加的代码就不具体说,具体说下事件的代码,这才…

SpringBoot项目使用Schedule注释创建定时任务

文章目录知识讲解相关注释&#xff08;主要两个,EnableScheduling和Scheduled&#xff09;scheduled的cron语法代码项目目录结构启动类&#xff08;Application&#xff09;定时任务类(Task)配置类&#xff08;application.properties&#xff09;pom依赖展望&#xff08;Quart…

环形链表相关的练习

目录 一、相交链表 二、环形链表 三、环形链表 || 一、相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据…

基于Three.js和MindAR实现的网页端WebAR人脸识别追踪功能的京剧换脸Demo(含源码)

前言 近段时间一直在玩MindAR的功能&#xff0c;之前一直在弄图片识别追踪的功能&#xff0c;发现其强大的功能还有脸部识别和追踪的功能&#xff0c;就基于其面部网格的例子修改了一个国粹京剧的换脸程序。如果你不了解MindAR的环境配置可以先参考这篇文章&#xff1a;基于Mi…

本地存储localStorage、sessionStorage

目录 一、localStorage 二、sessionStorage 三、本地存储处理复杂数据 一、localStorage 介绍 &#xff08;1&#xff09;数据存储在用户浏览器中 &#xff08;2&#xff09;设置、读取方便、甚至页面刷新不会丢失数据 &#xff08;3&#xff09;容量较大&#xff0c;se…

408考研计算机之计算机组成与设计——知识点及其做题经验篇目3:指令的寻址方式

上篇文章我们讲到&#xff0c;指令的基本格式&#xff0c;一条指令通常包括操作码字段和地址码字段两部分&#xff1a; 操作码字段地址码字段并且我们还讲到根据操作数地址码的数目不同&#xff0c;可将指令分为零一二三四地址指令。感兴趣的小伙伴们可以看看小编的上一篇文章…

贝塞尔曲线介绍及其应用

贝塞尔样条是一个允许用户控制节点处斜率的样条&#xff0c;是一种特殊的三次样条。   皮埃尔贝塞尔在其为雷诺&#xff08;Renault&#xff09;汽车公司工作时有了这个创意。Paul de Casteljau在与雷诺竞争关系的汽车公司雪铁龙Citroen公司工作时也独立有了这个想法。这在两…

联合解决方案 | 亚信科技AntDB数据库携手浪潮K1 Power赋能关键行业数字化转型,助力新基建

自2022年印发《“十四五”数字经济发展规划》以来&#xff0c;我国数字化发展进入快车道。数据库作为数据存储与计算的基础软件&#xff0c;对筑牢数字经济底座至关重要。服务器是承载数据的重要载体&#xff0c;在数据库性能可以通过扩容而无上限提升的情况下&#xff0c;数据…

老爸:“你做的什么游戏测试简直是不务正业!”——我上去就是一顿猛如虎的解释。

经常有人问我&#xff1a;游戏测试到底是干什么呢&#xff1f;是游戏代练&#xff1f;每天玩游戏&#xff1f;装备随便造&#xff0c;怪物随便秒&#xff0c;线上GM指令随便用&#xff1f;可以每天玩玩游戏&#xff0c;不用忙工作&#xff0c;太爽了&#xff1f;有时朋友不理解…

1638_chdir函数的功能

全部学习汇总&#xff1a;GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 今天看一个半生不熟的小函数&#xff0c;chdir。说半生不熟&#xff0c;是因为这个接口一看就知道是什么功能。然而&#xff0c;这个接口如何用可真就没啥想法了。 …

【微信小程序】-- 自定义组件 -- 数据、方法和属性(三十三)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…

设计模式之门面模式(外观模式)

目录 1.模式定义 2.应用场景 2.1 电源总开关例子 2.2 股民炒股场景 ​编辑 3. 实例如下 4. 门面模式的优缺点 传送门&#xff1a; 项目中用到的责任链模式 给对象讲工厂模式&#xff0c;必须易懂易会 策略模式&#xff0c;工作中你用上了吗&#xff1f; 1.模式定…

Linux order(文件、磁盘、网络、系统管理、备份压缩)

1. Linux 文件命令 -rwxrwxrwx chmod&#xff1a;change mode&#xff0c;用于&#xff08;文件所有者或 root &#xff09;变更用户(u:owner g:group o:other a:all)的权限 chmod [OPTION]… MODE[,MODE]… FILE… OPTION -R&#xff1a;递归修改more option&#xff1a;chmod…

【WPS文字-Word】WPS文字设置段落居中对齐后公式左边右边的文字仍然无法跟公式对齐,公式和文字对不齐

一、问题背景 原来的公式左边文字是底端&#xff0c;右边文字是居中&#xff0c;我想着让左右文字全跟公式居中对齐&#xff0c;就全部设置了段落居中对齐。 结果发现&#xff0c;公式左右边的文字依然无法居中对齐。左边的文字是居中&#xff0c;但是右边的文字变成了顶端对…

数据推介⎮情感语音合成音库

在语音交互领域&#xff0c;语音合成是重要的一环&#xff0c;其技术也在不断发展。近年来&#xff0c;人们对情感合成的兴趣和需求越来越高。情感语音合成会让机器如真人一样和我们交流&#xff0c;它可以用愤怒的声音、开心的声音、悲伤的声音等不同情绪来表达&#xff0c;甚…