返回题解分享
讨论 / 题解分享/ 帖子详情

统计子矩阵(编程题) - 题解

#### 二维前缀和+双指针

#include<iostream> 
using namespace std; 
typedef long long ll; 
const int N = 510; 
int n,m,k; 
int a[N][N]; 

int main(){
	cin >> n >> m >> k;
	for(int i=1;i<=n;i++){ 
		for(int j=1;j<=m;j++){
			cin>>a[i][j]; 
			a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1]; // 计算到当前位置的子矩阵元素和
		}
	} 
	ll ans =0;
	for(int i=1;i<=m;i++){ 
		for(int j=i;j<=m;j++){ 
			for(int s=1,t=1;t<=n;t++){ 
				while(s<=t && a[t][j]-a[s-1][j]-a[t][i-1]+a[s-1][i-1]>k)s++; // 调整下边界,直到子矩阵的元素和不超过k
				if(s<=t) ans+= t-s+1; // 如果下边界在上边界之下,累加可能的子矩阵数量
			}
		}
	}
	cout << ans << '\n'; 
}


i是左边界,j是右边界
s为上边界,t为下边界

通过 while 循环来实现的,循环会不断地移动下边界 s,直到找到一个和小于或等于 k 的子矩阵为止。
0 回复 0 转发 0 喜欢 2 阅读
回复 (0)
默认 最新
暂无回复,快来抢沙发!