小 A 有一张 M 行 N 列的地形图,每个格子有一个海拔高度。我们需要从图中找到一个 3×3 的正方形区域作为停机坪,要求该区域内 最大值与最小值之差不超过 H。在满足条件的所有区域中,求出 9 个格子海拔之和的最大值。
由于数据范围 M,N≤1000,整个地形图最多有 106 个格子。所有可能的 3×3 区域个数大约为 (M−2)×(N−2),也在 106 级别。
对于每个候选区域,我们只需要检查 9 个格子,统计它们的和、最大值和最小值。总计算量大约为 9×106,对于 C++ 来说完全可以在一秒之内完成。因此,直接采用暴力枚举即可通过本题。
具体步骤如下:
max_sum = 0。local_sum;local_max 和 local_min。local_max - local_min <= H,则用 local_sum 更新全局最大和 max_sum。max_sum。cpp1#include <iostream> 2using namespace std; 3 4int a[1010][1010]; // 存储地形图高度,多开一些空间防止越界 5 6int main() { 7 int M, N, H; 8 cin >> M >> N >> H; 9 10 // 读入矩阵 11 for (int i = 1; i <= M; ++i) { 12 for (int j = 1; j <= N; ++j) { 13 cin >> a[i][j]; 14 } 15 } 16 17 int max_sum = 0; // 记录满足条件的最大海拔和 18 19 // 枚举所有 3×3 区域的左上角 (i, j) 20 for (int i = 1; i <= M - 2; ++i) { 21 for (int j = 1; j <= N - 2; ++j) { 22 // 初始化当前区域的最大、最小、总和 23 int local_max = a[i][j]; 24 int local_min = a[i][j]; 25 int local_sum = 0; 26 27 // 遍历 3×3 区域中的每个格子 28 for (int x = 0; x < 3; ++x) { 29 for (int y = 0; y < 3; ++y) { 30 int height = a[i + x][j + y]; 31 local_sum += height; 32 if (height > local_max) local_max = height; 33 if (height < local_min) local_min = height; 34 } 35 } 36 37 // 判断极差是否不超过 H 38 if (local_max - local_min <= H) { 39 if (local_sum > max_sum) { 40 max_sum = local_sum; 41 } 42 } 43 } 44 } 45 46 cout << max_sum; 47 return 0; 48}
a[1010][1010] 留有余量,避免边界问题。x 和 y 从 0 到 2,正好遍历 3×3 的格子。local_max - local_min <= H 时才考虑更新 max_sum,保证了答案始终合法。max_sum 初始化为 0 是安全的。虽然本题直接暴力即可,但如果数据范围增加到 M,N≤3000 或更大,我们可以考虑以下优化:
不过对于本题数据规模,上述优化并非必需,暴力枚举已经足够清晰高效。
本题考查了二维数组的基本遍历和极差条件的判断,是一道典型的枚举模拟题。关键点在于正确设定枚举边界,以及对每个候选区域完整统计和与最值。只要细心实现,就能轻松通过。