题意:
给定一个 的二维矩阵,每个位置为 0 或者 1。
询问所有 的子矩阵中存在
的矩阵个数。
解法:
二维前缀和。
先从一维说起, 个元素的一维数组为
,下标从
到
。
那么对应的前缀和数组 的定义为:
求前缀和的递推式为:
代码实现:
s[0] = 0; for(int i = 1; i <= n; i++) s[i] = s[i - 1] + a[i];
利用前缀和,我们可以 求一段区间
的和。
再到二维前缀和:
求二维前缀和的递推式为: 。
求一个子矩阵
的和为:
。
会二维前缀和,那么这道题就结束了。
先求出二维前缀和,然后遍历所有 的子矩阵,判断和是否非零,统计答案。
Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 5;
int n, m, k, a[N][N], s[N][N];
int main() {
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
scanf("%1d", &a[i][j]);
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
}
int ans = 0;
for(int i = k; i <= n; i++)
for(int j = k; j <= m; j++) {
int v = s[i][j] - s[i - k][j] - s[i][j - k] + s[i - k][j - k];
if(v) ans++;
}
printf("%d\n", ans);
return 0;
}

京公网安备 11010502036488号