当前位置: 首页 > news >正文

AcWing 4964.子矩阵

首先就是运用了暴力的思路,能够过个70%的数据,剩下的直接时间超时了,没办法优化了。

讲一下暴力的思路:

其实就是模拟而已,也就是看作想要找的矩阵为一个小窗口,然后不断移动的事而已。

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath> 
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 1005
#define int long long
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
vector<int>cunchu;
int arr[MAX][MAX];
signed main() {ios::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);int n, m;int a, b;cin >> n >> m >> a >> b;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++)cin >> arr[i][j];}int sum = 0;//计算结果int left1 = 1;//这里代表的是对于上界的限制int left2 = a;//代表对于下界的限制int right1 = 1;//代表对于左边的限制int right2 = b;//代表对于右边的限制while (left2 <= n) {cunchu.clear();if (right2 > m){right1 = 1;right2 = b;left2++;left1++;continue;}for (int i = left1; i <= left2; i++) {for (int j = right1; j <= right2; j++) {cunchu.push_back(arr[i][j]);}}sort(cunchu.begin(), cunchu.end());sum += (cunchu.front() * cunchu.back()) % 998244353;right1++;right2++;}cout << sum;return 0;
}

接下来就是优化版本:

这里用的是滑动窗口问题的解决方法,也就是所谓数据结构中的单调队列,这也是需要一些数据结构基础的才能接受的知识点。

思路:单调队列讲究的就是一个单调,我们可以先套用单调队列的模板,可以参考一下y总的模板,作者的模板也是跟y总学的,建议首先理解,然后自己敲出来。

我们想,在给定的大矩阵当中,我们从中随便选一块小矩阵的大小,我们要求它的最大值最小值,如果要是暴力的话,复杂度肯定是n**2,而单调队列可以降到n,在求最值的时候我们尝试用单调队列进行求出。但是,我们以往用的单调队列都是线性的,也就是一维的,但不是二维的,怎么办?这样我们可以换个思路,可以从前面写的那个二维双指针可以知道,我们可以把二维问题变成一维的,也就是说,首先固定两个相对的边界。

假设我们这里就首先固定了左右边界,这个时候列数是不是就是小矩阵的长呢?可以自己画图看一下。这个时候,如果说我们先求出来每一行的最大值,再来求每一列的最小值,这两个过程是不是都是线性的呢?是的,这个时候我们的单调队列才派上用场。

对于每一行的最值求完之后,我们还需要对于这些最值中再求最值,这样才能是小矩阵的最值,所以又需要用一次单调队列,这样虽然麻烦,但是效率却是很高的。OK,核心思路就到这里

上代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<cmath> 
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<sstream>
#include<map>
#include<limits.h>
#include<set>
#define MAX 1005
#define int long long
#define _for(i,a,b) for(int i=a;i<(b);i++)
#define ALL(x) x.begin(),x.end()
using namespace std;
vector<int>cunchu;
int arr[MAX][MAX];//存储的大矩阵
int rmax[MAX][MAX], rmin[MAX][MAX];//对于第i-1行的每一个长度为b的窗口求最大/小值
int q[MAX];//队列
int one[MAX], two[MAX], three[MAX];//用来存储列的最值的
void get_max(int a[], int b[], int total, int qujian) {int front = 0;int rear = -1;for (int i = 0; i < total; i++) {if (front <= rear && q[front] + qujian <= i)front++;//当前队头滑出窗口while (front <= rear && a[q[rear]] <= a[i])rear--;//队尾元素比进来的元素小,那么我们就开始更新q[++rear] = i;if (i >= qujian - 1)//滑动窗口已经完全在数组里面进行滑动了,就开始统计每个窗口的最大值。b[i] = a[q[front]];}
}
void get_min(int a[], int b[], int total, int qujian) {int front = 0;int rear = -1;for (int i = 0; i < total; i++) {if (front <= rear && q[front] <= i - qujian)front++;while (front <= rear && a[q[rear]] >= a[i])rear--;q[++rear] = i;if (i >= qujian - 1)b[i] = a[q[front]];}
}
signed main() {ios::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);int n, m;int a, b;cin >> n >> m >> a >> b;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++)cin >> arr[i][j];}for (int i = 0; i < n; i++) {get_max(arr[i], rmax[i], m, b);//对于每一行的每一个长度为b的窗口求最大值get_min(arr[i], rmin[i], m, b);//对于每一行的每一个长度为b的窗口求最小值}int count = 0;//用来统计积的和//这里的外循环是对于列的遍历,内循环才是对于行的遍历for (int i = b-1; i < m; i++) {//为什么初值是b-1呢?这个时候窗口的队头才是i=0,初值不是b-1的话,窗口是不满的for (int j = 0; j < n; j++) one[j] = rmax[j][i];//这个时候我们对于每一行的当前窗口的最大值进行存储get_max(one, two, n, a);//这里是对于这些行的最大值再进行求最大值,也就是小矩阵的最大值了for (int j = 0; j < n; j++)one[j] = rmin[j][i];//同理,求最小值get_min(one, three, n, a);for (int j = a - 1; j < n; j++) {//为什么这里用a-1当初值呢?其实也是窗口的问题,如果纵向看,窗口的宽就是a了,如果初值不是a-1,窗口也是不满的count = (count + two[j] * three[j]) % 998244353;//这样就是对于所有小矩阵的最值进行相乘然后相加取模了}}cout << count;return 0;
}

相关文章:

AcWing 4964.子矩阵

首先就是运用了暴力的思路&#xff0c;能够过个70%的数据&#xff0c;剩下的直接时间超时了&#xff0c;没办法优化了。 讲一下暴力的思路&#xff1a; 其实就是模拟而已&#xff0c;也就是看作想要找的矩阵为一个小窗口&#xff0c;然后不断移动的事而已。 #include<ios…...

代码随想录算法训练营第day20|530.二叉搜索树的最小绝对差 、 501.二叉搜索树中的众数 、236. 二叉树的最近公共祖先

530.二叉搜索树的最小绝对差 力扣题目链接 (opens new window) 给你一棵所有节点为非负值的二叉搜索树&#xff0c;请你计算树中任意两节点的差的绝对值的最小值。 示例&#xff1a; 提示&#xff1a;树中至少有 2 个节点。 二叉搜索树是一颗有序的树&#xff0c;可以通过中…...

Hystrix的原理及应用:构建微服务容错体系的利器(二)

本系列文章简介&#xff1a; 本系列文章旨在深入剖析Hystrix的原理及应用&#xff0c;帮助大家理解其如何在微服务容错体系中发挥关键作用。我们将从Hystrix的核心原理出发&#xff0c;探讨其隔离、熔断、降级等机制的实现原理&#xff1b;接着&#xff0c;我们将结合实际应用场…...

【nuget】如何移动 nuget 缓存文件夹

如何移动 nuget 缓存文件夹 一、了解NuGet包的默认存放路径二、为什么需要修改NuGet包的默认存放路径?使用下面的命令查看本地包位置三、更改下载的NuGet包存储位置四、修改VS离线包引用地址五、验证修改的新路径是否成功默认情况下,NuGet下载的包存放在系统盘(C盘中),这样一…...

H266开源视频编码器VVENC现状

VVenC 是由 Fraunhofer HHI 研究团队开发的&#xff0c;主要是视频编码系统组。HHI 是欧洲最大的研究组织 Fraunhofer 协会的成员&#xff0c;该协会是德国的一个大型非营利性组织。源代码在&#xff1a; https://github.com/fraunhoferhhi/vvenc VVenC几乎与H.266视频标准同时…...

unity webgl怎么获取当前页面网址

在Unity WebGL中&#xff0c;你可以使用Javascript和C#的互操作性来获取当前页面的网址。以下是如何实现的步骤和示例代码&#xff1a; 首先&#xff0c;你需要创建一个Javascript脚本来获取当前页面的网址。&#xff08;简单方法为&#xff1a;创建xxx.txt&#xff0c;修改文件…...

深度学习神经网络训练环境配置以及演示

&#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&#xff09;开发基础教程 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人生秘诀&#xff1a;学习的本质就是极致重复! 目录 1 NVIDIA Dr…...

[嵌入式AI从0开始到入土]16_ffmpeg_ascend编译安装及性能测试

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注&#xff1a;等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间&#xff0c;后期会考虑出视频教程&#xff0c;务必催更&#xff0c;以防我变身鸽王。 第1期 昇腾Altas 200 DK上手 第2期 下载昇腾案例并运行 第3期 官…...

HTML5:七天学会基础动画网页11

CSS3动画 CSS3过渡的基本用法: CSS3过渡是元素从一种样式逐渐改变为另一种样式的效果。 过渡属性-transition 值与说明 transition-property 必需&#xff0c;指定CSS属性的name&#xff0c;transition效果即哪个属性发生过渡。 transition-duration 必需&#xff0c;t…...

考虑开发容器的 6 个理由

虽然在容器环境内进行开发的行为可以追溯到 2010 年代中期&#xff0c;但开发容器本身在过去一年中已经开始流行。微软在 2022 年推出了开发容器规范&#xff0c;推动了这一概念的发展&#xff0c;而 Docker 在去年夏天也紧随其后&#xff0c;推出了开发环境功能的测试版。 开…...

Python基础入门 --- 1-2.字面量

文章目录 Python基础入门第一章&#xff1a;1.1 第一个python程序 第二章 &#xff1a;2.1 字面量2.2 常用的值类型2.3 字符串2.3.1 三种定义方式2.3.2 引号嵌套2.3.3 字符串拼接2.3.4 字符串格式化2.3.5 格式化的精度控制数字精度控制&#xff1a; 2.3.6 字符串格式化方式22.3…...

华为云计算hcie认证考什么?华为hciie认证好考吗

1.理论知识&#xff1a;HCIE认证首先要求考生具备扎实的云计算理论基础&#xff0c;包括云计算的基本概念、架构、关键技术、安全管理等方面的知识。考生需要深入理解云计算的核心原理&#xff0c;以及华为云计算产品的特点和优势。 2.实践技能&#xff1a;除了理论知识外&…...

redis spring cache

数据库的数据是存储在硬盘上的&#xff0c;频繁访问性能较低。如果将一些需要频繁查询的热数据放到内存的缓存中&#xff0c;可以大大减轻数据库的访问压力。 SpringCache SpringCache提供基本的Cache抽象&#xff0c;并没有具体的缓存能力&#xff0c;需要配合具体的缓存实现…...

图解I/O中的零拷贝技术

什么是零拷贝&#xff1f; 零拷贝是一种计算机系统中的 I/O 优化技术&#xff0c;它的核心思想是在数据传输过程中尽可能地减少或完全避免 CPU 将数据从一个存储区域复制到另一个存储区域的操作&#xff0c;从而减少了上下文切换和 CPU 拷贝时间&#xff0c;提高了系统的性能和…...

【设计模式】Java 设计模式之桥接模式(Bridge)

桥接模式&#xff08;Bridge Pattern&#xff09;是结构型设计模式的一种&#xff0c;它主要解决的是抽象部分与实现部分的解耦问题&#xff0c;使得两者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;因为该模式涉及如何组合接口和它们的实现。将抽象部分与实现…...

记录dockers中Ubuntu安装python3.11

参考&#xff1a; docker-ubuntu 安装python3.8,pip3_dockerfile ubuntu22 python3.8-CSDN博客...

【算法专题--双指针算法】leetcode--283. 移动零、leetcode--1089. 复写零

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1. 移动零&#xff0…...

【JavaEE -- 多线程3 - 多线程案例】

多线程案例 1.单例模式1.1 饿汉模式的实现方法1.2 懒汉模式的实现方法 2. 阻塞队列2.1 引入生产消费者模型的意义&#xff1a;2.2 阻塞队列put方法和take方法2.3 实现阻塞队列--重点 3.定时器3.1 定时器的使用3.2 实现定时器 4 线程池4.1 线程池的使用4.2 实现一个简单的线程池…...

k8s的pod服务升级,通过部署helm升级

要通过Helm升级Kubernetes&#xff08;k8s&#xff09;中的Pod服务&#xff0c;你可以按照以下步骤进行操作&#xff1a; 安装Helm&#xff1a; 如果你还没有安装Helm&#xff0c;可以通过官方文档提供的方式进行安装。添加Helm仓库&#xff1a; 确保你已经添加了包含你要升级…...

复现文件上传漏洞

一、搭建upload-labs环境 将下载好的upload-labs的压缩包&#xff0c;将此压缩包解压到WWW中&#xff0c;并将名称修改为upload&#xff0c;同时也要在upload文件中建立一个upload的文件。 然后在浏览器网址栏输入&#xff1a;127.0.0.1/upload进入靶场。 第一关 选择上传文件…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...