题目:
基本思路:
1.读值,没什么说的。
2.求前缀和数组,前缀数组就是包括此数组的位置的左上角所有的数组数字和。这里使用了动态规划的思路。
推导公式:
这个公式的含义是,sum[i][j]
表示从矩阵左上角(1,1)到右下角(i,j)的矩形区域的和。它可以通过将矩阵分解为四个部分来计算:左上部分sum[i-1][j-1]
、上方部分sum[i-1][j]
、左侧部分sum[i][j-1]
,以及当前元素A[i][j]
。通过减去重复计算的部分sum[i-1][j-1]
,可以得到正确的结果。
3.根据前缀和数组来计算范围内的和。
计算公式:
草稿,我知道有很多错的地方,但是能理解就行,自己看着代码写写画画吧。
4.判断下,满足条件,结果数就+1。最后返回。
参考博客——java版本的:
代码:
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n, L, r, t;
cin >> n >> L >> r >> t;
int A[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> A[i][j];
}
}
// 求出前缀和数组
int sum[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + A[i][j];
}
}
int result = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
int x1 = max(1, i - r);
int x2 = min(n, i + r);
int y1 = max(1, j - r);
int y2 = min(n, j + r);
int tarSum = sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
if (tarSum <= t * (x2 - x1 + 1) * (y2 - y1 + 1))
result++;
}
}
cout << result;
return 0;
}