AcWing 4405. 统计子矩阵(双指针,前缀和)

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

输入格式

第一行包含三个整数 N , M N,M N,M 和 K K K。

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

输出格式

一个整数代表答案。

数据范围

对于 30 30% 30 的数据, N , M ≤ 20 N,M≤20 N,M≤20,

对于 70 70% 70 的数据, N , M ≤ 100 N,M≤100 N,M≤100,

对于 100 100% 100 的数据, 1 ≤ N , M ≤ 500 ; 0 ≤ A i j ≤ 1000 ; 1 ≤ K ≤ 2.5 × 1 0 8 1≤N,M≤500;0≤Aij≤1000;1≤K≤2.5×10^8 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 个。

没想到同一道题,仅仅是隔了一天,再一次遇见就又不会写了,所以复习很重要。。

对于此题,时间限制为 1 s 1s 1s,而矩阵的行和列的范围为 0 0 0到 500 500 500,假如我们暴力枚举每一行每一列,就会有 500 500 500的四次方的时间复杂度,肯定爆了,但是假如只枚举行,就会有 500 500 500的平方的复杂度,再加上运用双指针来扫描列,时间复杂度就不会爆了。

那么可以在处理前缀和的时候仅处理列前缀和,也就是不再处理出整个矩阵的前缀和,因为我们要枚举行。

之后再使用双指针扫描列,比如使用 l l l和 r r r。

  • 首先定义 l l l和 r r r为 1 1 1(初始下标),然后每次循环以 r r r为主线,让 r r r自增
  • 在循环中,首先处理出来 1 1 1 ~ r r r列(在我们枚举的行的区间中)的总和,如果这个总和大于了$k,就让总和减去 l l l列的总和,然后让 l l l往右走(因为这时候如果r在比较靠左的位置就已经大于k了,如果r再往右走,就也一定会大于 k k k,那么就必须让 l l l往右走),并且在一次加和大于 k k k之后,每次 r r r往右走, l l l都肯定要往右走,这里不需要进行判断或是什么。

代码:

cpp 复制代码
#include<iostream>
using namespace std;
const int N = 510;
#define ll long long
ll s[N][N];
int n, m, k;
int main() {
	cin >> n >> m >> k;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> s[i][j];
			s[i][j] += s[i - 1][j]; //处理列前缀和
		}
	}

	ll res = 0;
	for (int i = 1; i <= n; i++) {      //枚举行
		for (int j = i; j <= n; j++) {
			//注意这里sum定义到for里,因为在双指针扫描的过程中sum的值不能被初始化
			for (int l = 1, r = 1, sum = 0; r <= m; r++) {  
				sum += s[j][r] - s[i-1][r]; //先加上r列的总和
				while (sum > k) {           //如果超过了
					sum -= s[j][l] - s[i - 1][l];
					l++;   //在sum > k之后,每次r走,j必定走
				}

				res += r - l + 1;   //矩阵数量
			}
		}
	}
	cout << res;
	return 0;
}
相关推荐
可编程芯片开发2 小时前
基于MATLAB的PEF湍流风场生成器模拟与仿真
算法
罗西的思考2 小时前
【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 --- (9)--- Reward Judging
人工智能·算法·机器学习
Mr.HeBoYan3 小时前
一次持续三天才出现的丢包故障——深入解析 DPDK Memory Ordering、rte_ring 与 CPU Memory Barrier (下)
linux·网络·算法·架构·dpdk
wabs6664 小时前
关于图论【深度优先搜索的理论基础】
算法·深度优先·图论
先吃饱再说5 小时前
LeetCode 101. 对称二叉树
算法
是Dream呀5 小时前
人眼看不出的伪造,AI如何识别?实测合合信息跨模态鉴伪与去反光技术
算法
QN1幻化引擎6 小时前
SFA 信号场注意力:用8KB参数换248x KV Cache压缩,边缘设备也能跑长序列
人工智能·算法·gitee·gitlab
段一凡-华北理工大学6 小时前
向量数据库实战:选型、调优与落地~系列文章03:向量相似度算法全解:余弦、欧氏、内积,到底该用哪个?
大数据·数据库·人工智能·算法·机器学习·向量相似度·高炉炼铁
cjr_xyi7 小时前
AT1202Contest_c binarydigit 题解
c语言·c++·算法
atunet8 小时前
从算法优化到系统加速的多层级思考7
算法