题意:
给定一个 的二维矩阵,每个位置为 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; }