草庐IT

第十三届蓝桥杯b组c++ 统计子矩阵(暴力解,和滑动窗口优化)

不学会动态规划不改名 2023-08-15 原文

题目: 

给定一个 N×M 的矩阵 A,请你统计有多少个子矩阵 (最小 1×1,最大 N×M) 满足子矩阵中所有数的和不超过给定的整数 K?

输入格式
第一行包含三个整数 N,M 和 K。

之后 N 行每行包含 M 个整数,代表矩阵 A。

输出格式
一个整数代表答案。

数据范围
对于 30% 的数据,N,M≤20,
对于 70% 的数据,N,M≤100,
对于 100% 的数据,1≤N,M≤500;0≤Aij≤1000;1≤K≤2.5×108。

输入样例:
3 4 10
1 2 3 4
5 6 7 8
9 10 11 12
输出样例:
19
样例解释
满足条件的子矩阵一共有 19,包含:

大小为 1×1 的有 10 个。
大小为 1×2 的有 3 个。
大小为 1×3 的有 2 个。
大小为 1×4 的有 1 个。
大小为 2×1 的有 3 个。

暴力解法:(能得百分之七十的分数)

思路:和我之前写的  在数组中找子数组和小于k的子数组的个数。思路一样 ,只不过今天这道题是二维的 ,用pre[i][j]来表示第i行前j列的前缀和,将i  作为左界限,j作为右界限

矩阵的宽度用i,j两个变量用双指针遍历每一种宽度的可能性,例如i=0,j=1的时候遍历的是第一列1,5,9

矩阵的高度利用i1,i2两个变量用双指针遍历每一种高度的可能性

从第一列开始,矩阵的和必须要小于10的矩阵个数,sum=sum+pre【i2】【j】-pre【i2】【i】;

如果小于k,cnt++;

全部代码:

#include<iostream>
using namespace std;
int n, m;
int dp[1005][1005];
int a[1005][1005];
int pre[1005][1005];
int  ans, sum;
int k, cnt;
int main() {
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> a[i][j];
			ans = max(ans, a[i][j]);
			pre[i][j] = pre[i][j - 1] + a[i][j];//第i行前j列的数字和

		}
	}
	for (int i = 0; i < m; i++) {//结束列
		for (int j = i + 1; j <= m; j++) {//初始列
			sum = 0;
			for (int i1 = 1; i1 <= n; i1++) {
				sum = 0;
				for (int i2 = i1; i2 <= n; i2++) {
					sum = sum + pre[i2][j] - pre[i2][i];
					if (sum <= k) {
						cout << "sum:" << sum;
						cnt ++;
						cout << "cnt:" << cnt << endl;
					}
				}

			}

		}
	}
	cout << cnt << endl;
	return 0;

}

(2)滑动窗口优化(时间复杂度为o(n3))

全部代码:

方法一:

#include<iostream>
using namespace std;
int n, m;
int a[1005][1005];
int pre[1005][1005];

int k;
long long cnt;
int main() {
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> a[i][j];
			pre[i][j] = pre[i][j - 1] + a[i][j];//前缀和,第i行前j列的数字和

		}
	}
	for (int i = 0; i <m; i++) {//初始列
		for (int j = i + 1; j <= m; j++) {//结束列
			int sum = 0;
			
			for (int r =1 ,l = 1; r <= n; r++) {//r  尾指针,l表示起指针
				sum += pre[r][j] - pre[r][i];
				//cout << "sum:" << sum << endl;
				while (r >=l&& sum > k) {
					sum -= pre[l][j] - pre[l][i];
					l++;
				} 
				if (r >=l) {
					cnt += r - l + 1;
					//cout<<"cnt:"<<cnt<<endl;
				}	
			
			}
		}
	}
	cout << cnt << endl;
	return 0;
}

方法二:

#include<iostream>
using namespace std;
typedef long long LL;
const int N = 510;
LL n, m, k;
LL a[N][N], s[N][N];
//求子矩阵的和
LL sum(int x1, int y1, int x2, int y2) {
    return s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1];
}

int main()
{
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> a[i][j];
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
        }
    }
    LL ans = 0;
    for (int x1 = 1;x1 <= n; x1++) {
        for (int x2 = x1; x2 <= n; x2 ++) {
            for (int y1 = 1, y2 = 1; y2 <= m; y2++) {
                while (y1 <= y2 &&(long long )s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]> k) y1++;
                ans =ans+ y2 - y1 + 1;
            }
        }
    }
    cout << ans <<endl;
    return 0;
}


有关第十三届蓝桥杯b组c++ 统计子矩阵(暴力解,和滑动窗口优化)的更多相关文章

  1. 旋转矩阵的几何意义 - 2

    点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度;     在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。

  2. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

  3. 华为OD机试真题 C++ 实现【带传送阵的矩阵游离】【2023 Q2 | 200分】 - 2

            所有题目均有五种语言实现。C实现目录、C++实现目录、Python实现目录、Java实现目录、JavaScript实现目录题目n行m列的矩阵,每个位置上有一个元素你可以上下左右行走,代价是前后两个位置元素值差的绝对值.另外,你最多可以使用一次传送阵(只能从一个数跳到另外一个相同的数)求从走上角走到右下角最少需要多少时间。输入描述:第一行两个整数n,m,分别代表矩阵的行和列。后面n行,每行m个整数,分别代表矩阵中的元素。输出描述:一个整数,表示最少需要多少时间。

  4. 蓝桥杯备赛(二) - 2

    目录前言: 一、ASC分析代码实现二、 卡片分析代码实现三、 直线分析代码实现四、货物摆放分析代码实现小结:前言:  在刷题的过程中,发现蓝桥杯的题目和力扣的差别很大。让人有一种不一样的感觉,蓝桥杯题目偏向对于实际问题用编程去的解决,而力扣给人感觉很锻炼自己的编程思维,逻辑能力。两者结合去刷,相信会有不一样的收获。 一、ASC  已知大写字母A的ASCII码为65,请问大写字母L的ASCII码是多少?分析  这道题目看上去很简单,我们需确定自己计算的准确,所以我建议用编程去解决。代码实现publicclassTest8{publicstaticvoidmain(String[]args){Sy

  5. Ruby 缺少常量表达式优化? - 2

    我希望Ruby的解析器会进行这种微不足道的优化,但似乎并没有(谈到YARV实现,Ruby1.9.x、2.0.0):require'benchmark'deffib1a,b=0,1whileb由于这两种方法除了在第二种方法中使用预定义常量而不是常量表达式外是相同的,因此Ruby解释器似乎在每个循环中一次又一次地计算幂常数。是否有一些Material说明为什么Ruby根本不进行这种基本优化或只在某些特定情况下进行? 最佳答案 很抱歉给出了另一个答案,但我不想删除或编辑我之前的答案,因为它下面有有趣的讨论。正如JörgWMittag所说,

  6. ruby-on-rails - 优化读取数据库和写入csv文件 - 2

    我正在尝试从数据库中读取大量单元格(超过100.000个)并将它们写入VPSUbuntu服务器上的csv文件。碰巧服务器没有足够的内存。我正在考虑一次读取5000行并将它们写入文件,然后再读取5000行,等等。我应该如何重构我当前的代码以使内存不会被完全消耗?这是我的代码:defwrite_rows(emails)File.open(file_path,"w+")do|f|f该函数由sidekiqworker调用:write_rows(user.emails)感谢您的帮助! 最佳答案 这里的问题是,当您调用emails.each时,

  7. 软约束、硬约束、Minimum Snap的轨迹优化方法 - 2

    文章目录前言约束硬约束的轨迹优化Corridor-BasedTrajectoryOptimizationBezierCurveOptimizationOtherOptions软约束的轨迹优化Distance-BasedTrajectoryOptimization优化方法前言可以看看我的这几篇Blog1,Blog2,Blog3。上次基于MinimumSnap的轨迹生成,有许多优点,比如:轨迹让机器人可以在某个时间点抵达某个航点。任何一个时刻,都能数学上求出期望的机器人的位置、速度、加速度、导数。MinimumSnap可以把问题转换为凸优化问题。缺点:MnimumSnap可以控制轨迹一定经过中间的

  8. 欧拉角表示的姿态矩阵(313和312转序) - 2

    一、习惯约定图片来自PSINS(高精度捷联惯导算法)PSINS工具箱入门与详解.pptx二、基本旋转矩阵绕x轴逆时钟旋转α\alphaα角度Rx(α)=[ 1000cos⁡αsin⁡α0−sin⁡αcos⁡α]R_x(\alpha)=\begin{bmatrix}\1&0&0\\0&\cos\alpha&\sin\alpha\\0&-\sin\alpha&\cos\alpha\end{bmatrix}Rx​(α)=​ 100​0cosα−sinα​0sinαcosα​​绕y轴逆时钟旋转α\alphaα角度Ry(α)=[ cos⁡α0−sin⁡α010sin⁡α0cos⁡α]R_y(\alpha

  9. 欧拉角、旋转矩阵及四元数 - 2

    欧拉角、旋转矩阵及四元数1.简介2.欧拉角2.1欧拉角定义2.2右手系和左手系2.3转换流程3.旋转矩阵4.四元数4.1四元数与欧拉角和旋转矩阵之间等效变换4.2测试Matlab代码5.总结1.简介常用姿态参数表达方式包括方向余弦矩阵、欧拉轴/角参数、欧拉角、四元数以及罗德里格参数等。高分辨率光学遥感卫星主要采用欧拉角与四元数对姿态参数进行描述。这里着重讲解欧拉角、旋转矩阵和四元数。2.欧拉角2.1欧拉角定义欧拉角是表征刚体旋转的一种方法之一,由莱昂哈德·欧拉引入的三个角度,用于描述刚体相对于固定坐标系的方向。在摄影测量、空间科学或其它技术领域,一般用一组(三个)欧拉角描述两个空间坐标之间的旋

  10. ruby-on-rails - 负载测试期间 Unicorn CPU 使用率激增,优化方法 - 2

    我对为我的RubyonRails3.1.3应用优化我的Unicorn设置的方法很感兴趣。我目前正在高CPU超大实例上生成14个工作进程,因为我的应用程序在负载测试期间似乎受CPU限制。在模拟负载测试中,每秒大约20个请求重放请求,我的实例上的所有8个内核都达到峰值,盒子负载飙升至7-8个。每个unicorn实例使用大约56-60%的CPU。我很好奇可以通过哪些方式对其进行优化?我希望能够每秒将更多请求汇集到这种大小的实例上。内存和所有其他I/O一样完全正常。在我的测试过程中,CPU越来越低。 最佳答案 如果您受CPU限制,您希望使用

随机推荐