📷 题解插图【CSP】CSP-XL 2025辽宁复赛真题-第二题, 积分(points)
CSP-XL 2025辽宁复赛真题-第二题,二维数组前缀和考点,个人认为约相当于GESP四级+,五级-,难度⭐⭐★☆☆。
CSP-XL 2025辽宁复赛真题-第二题, 积分(points)
题目要求

题目分析
解题思路
-
题意梳理
给定一个 的整数矩阵,每个格子有一个积分值。
再给出两个边长 和 ,要求分别找出所有边长为 的正方形区域与边长为 的正方形区域,计算它们内部积分之和,最终输出这两个“最大子正方形和”中的较大者。
若 或 大于矩阵行列尺寸,则对应尺寸无法形成合法正方形,跳过。 -
核心思路——二维前缀和
- 预处理:
构造二维前缀和数组pre_sum[i][j],表示从左上角 到 子矩阵的积分和。
递推式:
pre_sum[i][j] = pre_sum[i-1][j] + pre_sum[i][j-1] - pre_sum[i-1][j-1] + a_array[i][j]
这样可在 时间内算出任意子正方形和。 - 枚举:
分别用两重循环枚举所有可能的左上角 ,若i+k-1≤n且j+k-1≤m( 取 或 ),则用前缀和公式
sum = pre_sum[i+k-1][j+k-1] - pre_sum[i-1][j+k-1] - pre_sum[i+k-1][j-1] + pre_sum[i-1][j-1]
得到当前正方形积分,更新对应尺寸的最大值。 - 结果:
最终取max(max_x, max_y)输出即可。
- 预处理:
-
复杂度分析
- 时间:
预处理前缀和 ;
枚举所有 正方形最多 个, 同理,总体仍为 。 - 空间:
两个 的long long数组,约 。
- 时间:
-
边界与细节
- 当 或 大于 或 时,对应尺寸无法形成合法正方形,循环内提前
break减少无效枚举。 - 初始化最大值用
LLONG_MIN防止全负矩阵出错。 - 使用
freopen按复赛要求读写文件,行列下标统一从 1 开始,避免越界。
- 当 或 大于 或 时,对应尺寸无法形成合法正方形,循环内提前
示例代码
#include <algorithm>
#include <climits>
#include <iostream>
long long a_array[1005][1005]; // 存放原始二维数组,行列下标从1开始
long long pre_sum[1005][1005]; // 二维前缀和数组,pre_sum[i][j]表示(1,1)到(i,j)子矩阵的和
int main() {
freopen("points.in", "r", stdin); // 复赛标准输入文件
freopen("points.out", "w", stdout); // 复赛标准输出文件
int n, m, x, y; // n行m列,x×x与y×y两种尺寸的正方形区域
std::cin >> n >> m >> x >> y;
// 读入原始矩阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
std::cin >> a_array[i][j];
}
}
// 计算二维前缀和
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
pre_sum[i][j] = pre_sum[i - 1][j] + pre_sum[i][j - 1] -
pre_sum[i - 1][j - 1] + a_array[i][j];
}
}
// 枚举所有x×x正方形区域,求最大积分
long long max_x_points = LLONG_MIN; // 初始化为最小值
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (i + x - 1 <= n && j + x - 1 <= m) {
long long cur_points =
pre_sum[i + x - 1][j + x - 1] - pre_sum[i - 1][j + x - 1] -
pre_sum[i + x - 1][j - 1] + pre_sum[i - 1][j - 1];
max_x_points = std::max(max_x_points, cur_points);
} else {
break; // 当前行剩余位置无法满足x×x区域,直接跳出内层循环
}
}
}
// 枚举所有y×y正方形区域,求最大积分
long long max_y_points = LLONG_MIN;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (i + y - 1 <= n && j + y - 1 <= m) {
long long cur_points =
pre_sum[i + y - 1][j + y - 1] - pre_sum[i - 1][j + y - 1] -
pre_sum[i + y - 1][j - 1] + pre_sum[i - 1][j - 1];
max_y_points = std::max(max_y_points, cur_points);
} else {
break; // 同理,提前结束本行后续枚举
}
}
}
// 输出两种尺寸中的最大积分
long long max_points = std::max(max_x_points, max_y_points);
std::cout << max_points << std::endl;
return 0;
}
附:样例和测试数据下载地址:
链接:https://pan.quark.cn/s/79e0531a87ed?pwd=1bK8 提取码:1bK8
所有代码开源上传至 GitHub:yummy-code 仓库 · GESP 专题站:GESP WIKI
欢迎加入:C++ GESP/CSP 考级答疑群(688906745) 与 Java/Python交流群(982860385),点击可直接加群。
猜你想读 · 相关文章推荐
【CSP】CSP-XL 2025辽宁复赛真题-第三题, 小L打比赛(match)
CSP-XL 2025辽宁复赛真题-第三题,小L打比赛(match),贪心思想考点,个人认为约相当于GESP四级+,五级-,难度⭐⭐★☆☆。
【CSP】CSP-XL 2025辽宁复赛真题-第四题, 购物(buy)
CSP-XL 2025辽宁复赛真题-第四题,购物(buy),也是本次考试最后一题,难度最大,DFS思想考点,属于GESP六级考纲内容,难度⭐⭐⭐☆☆。
【CSP】CSP-J 2019 第一轮真题解析(一):单项选择题
2019 年是 NOIP 转型为 CSP 的第一年,本年度的 CSP-J(入门级/普及组)初赛试卷难度适中,非常注重计算机的基础理论广度以及算法执行的模拟能力。 本文将为您先展示真题原题,然后进行逐题深度解析,帮助 GESP 及 CSP-J 的备考同学精准对标考点。
OneCoder (lihongzheshuai)
一个中年人的自留地,记录学习 C++、GESP/NOI、Java、Python 与算法架构的心得体会。本站唯一网址:coderli.com