题目来源
洛谷
题目内容
领地选择
题目描述
作为在虚拟世界里统帅千军万马的领袖,小 Z 认为天时、地利、人和三者是缺一不可的,所以,谨慎地选择首都的位置对于小 Z 来说是非常重要的。
首都被认为是一个占地 C × C C\times C C×C 的正方形。小 Z 希望你寻找到一个合适的位置,使得首都所占领的位置的土地价值和最高。
输入格式
第一行三个整数 N , M , C N,M,C N,M,C,表示地图的宽和长以及首都的边长。
接下来 N N N 行每行 M M M 个整数,表示了地图上每个地块的价值。价值可能为负数。
输出格式
一行两个整数 X , Y X,Y X,Y,表示首都左上角的坐标。
样例 #1
样例输入 #1
3 4 2
1 2 3 1
-1 9 0 2
2 0 1 1
样例输出 #1
1 2
提示
对于 60 % 60\% 60% 的数据, N , M ≤ 50 N,M\le 50 N,M≤50。
对于 90 % 90\% 90% 的数据, N , M ≤ 300 N,M\le 300 N,M≤300。
对于 100 % 100\% 100% 的数据, 1 ≤ N , M ≤ 1 0 3 1\le N,M\le 10^3 1≤N,M≤103, 1 ≤ C ≤ min ( N , M ) 1\le C\le \min(N,M) 1≤C≤min(N,M)。
知识点
二维前缀和
题目思路
找 C ∗ C C*C C∗C 大小的方块的和最大值,想到和的累加,然后是二维的数据,就有维前缀和,首先前缀和计算某个位置一直累加到左上角的和,然后找 C ∗ C C*C C∗C 大小的左上位置和右下位置的前缀和做差得到当前的块的总和,最后比较出最大值并记录下来。
AC代码
```cpp
//
// Created by Jisam on 28/09/2024 11:18 PM.
// Solution of 领地选择
// 2024-09-28 23:28:40 AC 100 二维前缀和
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e4 + 4;
int a[MAXN][MAXN], b[MAXN][MAXN];
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
// 读取输入的变量N,M和C的值
int N, M, C;
cin >> N >> M >> C;
// 初始化二维数组a和b
int a[N + 1][M + 1], b[N + 1][M + 1];
// 通过输入构建二维前缀和数组b
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
cin >> a[i][j];
// 当前元素的值加上它左边、上边和左上角的前缀和元素的数量
b[i][j] = b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1] + a[i][j];
}
}
// 初始化最大值变量和最终位置变量
int _max = 0, ti, tj;
// 寻找最大值及其位置
for (int i = C; i <= N; i++) {
for (int j = C; j <= N; j++) {
// 计算当前子矩阵的元素数量,并与_max比较
int t = b[i][j] + b[i - C][j - C] - b[i - C][j] - b[i][j - C];
if (t > _max) {
_max = t;
ti = i, tj = j;
}
}
}
// 输出结果
cout << ti - C + 1 << " " << tj - C + 1 << endl;
return 0;
}