【前缀和+双指针】蓝桥杯2022第十三届统计子矩阵

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

输入格式:

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

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

输出格式

一个整数代表答案。

样例输入

复制代码
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 个。

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

对于 100% 的数据,1 ≤ N, M ≤ 500; 0 ≤ Ai j ≤ 1000; 1 ≤ K ≤ 250000000.

cpp 复制代码
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=510;
LL w[N][N];
LL s[N][N];
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
    	for(int j=1;j<=m;j++){
    		cin>>w[i][j];
    		//每一列的前缀和(一维)
    		s[i][j]=s[i-1][j]+w[i][j];
		}
	}
	LL sum=0,ans=0;
	//找j-i+1行,r-l+1列的子矩阵
	for(int i=1;i<=n;i++){//上边界
		for(int j=i;j<=n;j++){//下边界
			sum=0;
			for(int l=1,r=1;r<=m;r++){
				sum+=s[j][r]-s[i-1][r];
				while(l<=r&&sum>k){
					sum-=s[j][l]-s[i-1][l];
					l++;
				}
				ans+=r-l+1;
			}
		}
	}
	cout<<ans<<endl;
	//二维;
//    int n,m,k;
//    cin>>n>>m>>k;
//    for(int i=1;i<=n;i++){
//    	for(int j=1;j<=m;j++){
//    		cin>>w[i][j];
//    		s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+w[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&&s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]>k) y1++;
//				ans+=y2-y1+1;
//			}
//		}
//	}
//	cout<<ans<<endl;
    return 0;
}
相关推荐
Hello eveybody1 分钟前
介绍一下动态树LCT(Python)
开发语言·python·算法
不穿铠甲的穿山甲4 分钟前
MMR最大边际相关性
算法
handler016 分钟前
速通蓝桥杯省一:二分算法
c语言·开发语言·c++·笔记·算法·职场和发展·蓝桥杯
炽烈小老头7 分钟前
【 每天学习一点算法 2026/05/08】最小覆盖子串
学习·算法
汉克老师28 分钟前
GESP5级C++考试语法知识(十六、分治算法(三))
c++·算法·分治算法·汉诺塔·逆序对·gesp5级·gesp五级
V搜xhliang024631 分钟前
OpenClaw进阶完全教程
运维·人工智能·算法·microsoft·自动化
叼烟扛炮39 分钟前
C++ 知识点12 构造函数
开发语言·c++·算法·构造函数
满天星83035771 小时前
定长内存池ObjectPool
数据结构·c++·算法·链表
叼烟扛炮1 小时前
C++第八讲:string 类
开发语言·c++·算法·string
科研前沿1 小时前
像素级实景映射,构建实景孪生底层新范式
科技·矩阵·音视频