欢迎光临
我们一直在努力

GESP 2025年9月 排兵布阵 题解|这题枚举的坑一定要避开

今天继续刷 GESP 2025年9月 的真题。这道枚举题属于「思路简单但细节多」的类型,很多同学代码写完了却过不了,问题基本都出在下面要讲的几个点上。

题目来源:ACGO A94971 | 2025年9月 四级赛事场次:2025年9月 四级

一、题目信息

题目名称:排兵布阵

赛事场次:2025年9月 四级

难度定位:四级

涉及知识点:枚举

题目链接:https://www.acgo.cn/problemset/info/94971

坑点(无数人 WA 的核心)

  • 枚举范围的确定;如何用循环穷举全部可能。

题意简述

作为将军,你自然需要合理地排兵布阵。地图可以视为 n 行 m 列的网格,适合排兵的网格以 1 标注,不适合排兵的网格以 0 标注。现在你需要在地图上选择一个矩形区域排兵,这个矩形区域内不能包含不适合排兵的网格。请问可选择的矩形区域最多能包含多少网格?

前置知识

下面先把需要的基础知识理一遍,不熟悉的朋友可以跟着看,熟悉的直接跳过。

枚举的思路:把所有可能的情况逐个试一遍,在数据范围允许的前提下,这是最稳妥的做法。关键是确定枚举的范围和顺序,避免重复或漏解。

二、思路分析

先看清楚题目要我们做什么

把题目读两遍,我们提取出关键信息:输入是什么、要输出什么、有哪些约束条件。这道题考查的是枚举,属于这类题里比较基础的一道,把题目要求一步步翻译成代码逻辑就能解决。

解题步骤拆解

  • 按题目要求读入全部输入数据。
  • 按题意逐项处理,这一步是核心,要保证每一步都对应题目里的一句话。
  • 按题目规定的格式输出结果。
  • 需要说明的是,上面这个思路是把题目要求直译成代码得到的,没有用到什么高级技巧。对于这类基础题,读准题意加写对边界比追求巧妙解法更重要,因为考试里这种题是必须拿满分的。

    三、完整代码 + 逐行注释

    #include <algorithm>
    #include <cstdio>
    using namespace std;
    const int N = 15;
    int n, m;
    int a[N][N];
    int ans;
    int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) // 遍历
    for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]); // 遍历
    for (int u = 1; u <= n; u++) // 遍历
    for (int l = 1; l <= m; l++) // 遍历
    for (int d = u; d <= n; d++) { // 遍历
    int chk = 1;
    for (int r = l; r <= m; r++) { // 遍历
    for (int x = u; x <= d; x++) chk &= a[x][r]; // 遍历
    if (!chk) break; // 判断
    ans = max(ans, (r – l + 1) * (d – u + 1));
    }
    }
    printf("%d\\n", ans);
    return 0;
    }

    四、代码分段拆解

    为了看得更清楚,我们把代码按功能分成几段解释。

    第一步:引入头文件

    #include <algorithm>
    #include <cstdio>
    using namespace std;

    #include <iostream> 提供输入输出功能,using namespace std; 让我们能直接写 cin、cout 而不用加前缀。这两行是几乎所有 C++ 程序的开头,照写即可。

    第二步:读入数据

    scanf("%d%d", &n, &m);
    for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]);

    注意变量的类型要能装下题目的数据。数据可能超过 21 亿时要改用 long long。

    第三步:核心处理逻辑

    for (int i = 1; i <= n; i++)
    for (int u = 1; u <= n; u++)
    for (int l = 1; l <= m; l++)
    for (int d = u; d <= n; d++) {

    这一段是整道题的关键,也是枚举的体现。看循环的三个要素:从哪里开始、什么时候结束、每次怎么变化。这三个要素任何一个写错,结果都会不对。

    第四步:按要求输出

    printf("%d\\n", ans);

    输出格式必须和题目要求的完全一致。很多同学算法完全正确却因为少了一个换行或者空格多寡不对而 WA,这种分丢得最可惜。

    五、实例模拟

    下面用样例数据走一遍流程,你能看到每一步变量是怎么变化的。

    以题目的第一组样例为例:

    样例输入

    4 3
    0 1 1
    1 0 1
    0 1 1
    1 1 1

    样例输出

    4

    把这份输入代进代码,程序会先把数据依次读入,然后进入循环逐个判断,把满足条件的值累积起来,最后按格式输出。建议你对照着代码在纸上走一遍前两次循环,确认自己对每一步的理解都和程序一致。

    题目另外还给了 1 组样例,做完之后建议把剩下的样例都跑一遍,全部通过再提交,能避开大部分边界问题。

    六、踩坑总结

    下面是做这道题时最容易出错的地方,对照自己的代码检查一下:

  • 变量类型选错:虽然本题范围不大,但养成习惯——凡是不确定范围时,累加变量一律用 long long,成本为零但能保命。
  • 输出格式不符:题目要求输出几行就输出几行,行末换行、数字之间的空格都要严格对齐,算法对了但格式错了同样判 WA,这种分丢得最冤。
  • 特殊情况没特判:把最小数据、最大数据、答案恰好等于 0 的情况各测一遍。特别是边界输入,出题人最喜欢在这里设陷阱。
  • 七、知识点拓展

    这题虽然简单,但背后的方法可以推广,总结如下:

    • 本题考查枚举的基本写法,这类题在考试中属于必得分项,要练到能默写。
    • 写完代码后建议自己造几组边界数据测试,特别是最小值和最大值。
    • 同一知识点在不同场次反复出现,把这道题的写法吃透,后面遇到同类题可以直接套用。

    八、适用人群

    如果你已经掌握枚举的基本写法,这道题可以用来巩固手感。

    这道题就讲到这里。我会持续更新各场次真题的详细拆解,需要系统复习的同学可以关注这个系列。有问题欢迎评论区讨论。

    赞(0)
    未经允许不得转载:171主机测评 » GESP 2025年9月 排兵布阵 题解|这题枚举的坑一定要避开
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址