2026山西省信息学竞赛真题:二分答案解析

四季读书网 4 0
2026山西省信息学竞赛真题:二分答案解析

2026山西省信息学竞赛真题:二分答案解析

 📘 省赛冲刺特训|2026 年「全国中学生信息学奥林匹克竞赛(山西赛区)」报名已于 9 月 1 日启动、9 月 30 日截止,后续衔接 CSP-J/S 与 NOIP。二分答案是复赛与省赛的高频考点——它把「求最小 / 最大满足条件值」的问题,用「猜测 + 验证」压成 O(N·logS) 的稳解法。今天用一道原创真题拆解它。

2026山西省信息学竞赛真题:二分答案解析-第1张图片-四季读书网  

一、题目背景

读书节要把 N 本书运到展区,第 i 本书重量为 w[i]。运输必须按书的原始顺序装船,每艘船所载书的重量之和不能超过船的载重 W。组委会最多只能派出 M 艘船。请回答:在所有书都能运完的前提下,船的最小载重 W 是多少?

  • 输入:书的数量 N、最多船数 M、重量数组 w[1..N]
  • 输出:满足条件的最小整数载重 W
  • 约定:单本书重量不超过任何合理船载重,且一定能运完。

二、样例

输入:N=5, M=3,重量 w=[4, 8, 1, 5, 6]

输出:11(载重 11 时,3 艘船分别装 [4,8][1,5][6],恰好运完;载重 10 时需要 4 艘,不满足)。

2026山西省信息学竞赛真题:二分答案解析-第2张图片-四季读书网  

三、二分答案思路拆解

核心观察:船载重 W 越大,所需船数越少——这是典型的单调性。于是我们不必逐个试 W,而是:

  1. 定上下界
    :下界 L = max(w)(单本书至少得装下),上界 R = sum(w)(极端情况 1 艘船全装);
  2. 写判定函数ok(W)
    :贪心顺次装船,当前船加下一本书不超 W 就装,否则开新船;统计船数是否 ≤ M;
  3. 二分
    :当 ok(mid) 为真,说明 mid 可能偏大,令 R = mid;否则令 L = mid+1;直到 L==R 即为最小可行载重。

四、C++ 参考代码

#include <iostream> #include <vector> using namespace std;  // 判定:载重 W 时,能否用不超过 M 艘船运完 bool ok(const vector<long long>& w, int M, long long W) {     int ships = 1;     long long load = 0;     for (long long x : w) {         if (load + x > W) {        // 当前船装不下,开新船             ships++;             load = x;             if (ships > M) return false;         } else {             load += x;         }     }     return true; }  int main() {     int n, M;     if (!(cin >> n >> M)) return 0;     vector<long long> w(n);     long long L = 0, R = 0;     for (int i = 0; i < n; i++) {         cin >> w[i];         if (w[i] > L) L = w[i];   // 下界:最重的单本书         R += w[i];                // 上界:全部重量之和     }     while (L < R) {               // 二分答案         long long mid = L + (R - L) / 2;         if (ok(w, M, mid)) R = mid;         else               L = mid + 1;     }     cout << L << endl;            // L == R 即最小可行载重     return 0; }

五、Python 参考代码

def ok(w, M, W):     ships, load = 1, 0     for x in w:         if load + x > W:        # 当前船装不下,开新船             ships += 1             load = x             if ships > M:                 return False         else:             load += x     return True  def solve(w, M):     L = max(w)                 # 下界:最重的单本书     R = sum(w)                 # 上界:全部重量之和     while L < R:               # 二分答案         mid = (L + R) // 2         if ok(w, M, mid):             R = mid         else:             L = mid + 1     return L                   # L == R 即最小可行载重  # 样例 print(solve([4, 8, 1, 5, 6], 3))   # -> 11 
2026山西省信息学竞赛真题:二分答案解析-第3张图片-四季读书网  

六、复杂度与边界

  • 时间 O(N·logS),S 为重量总和量级,判定函数每次 O(N);
  • 空间 O(N) 存重量;
  • 边界:单本书就可能超过平均分配,故下界必须取 max(w) 而非 0;mid 用 L+(R-L)/2 防溢出;重量用 long long 防累加越界。

七、考点拆解(7 点)

  1. 答案的单调性
    :载重越大船数越少,这是二分答案成立的根本;
  2. 判定与求解分离
    :把「求最值」转成「判定可行性」,是二分答案的套路核心;
  3. 贪心验证
    :顺次装船统计船数,正确性来自「每段越短越省船」;
  4. 上下界设定
    :下界 max(w)、上界 sum(w),漏掉任一边都会错;
  5. 二分写法
    while(L<R) + mid=L+(R-L)/2 + 收敛到 L==R;
  6. 整数与溢出
    :重量用 64 位,mid 防溢出;
  7. 对拍验证
    :用「从小到大枚举 W 找首个可行」的暴力法对拍 5000 组随机数据,双解完全一致。

八、动手练一练

把样例改成 w=[3, 2, 7, 4, 5], M=2,最小载重是多少?再试试 M=3 会变成几?欢迎在评论区贴出你的运行结果,下期拆解「二分答案 + 前缀和」的进阶变体。

📚 免费少儿编程资料(夸克网盘领取)

以下资料来自夸克网盘分享。个人号链接暂不支持直接点击,请长按或复制下方链接,打开夸克网盘 App / 网页粘贴即可保存:

  1. 1. 全国青少年信息素养大赛复赛集训题目Python&C++.docx
    https://pan.quark.cn/s/93995d3cb150
  2. 2. 2024信息素养-智能算法应用挑战赛-复赛初中组题目7月7日.pdf
    https://pan.quark.cn/s/da97b5dbf75d
  3. 3. Python背记手册.pdf
    https://pan.quark.cn/s/7568ae9ca92b
  4. 4. Python课程
    https://pan.quark.cn/s/a94bf02d00c6
  5. 5. 2024信息素养大赛图形化复赛集训题答案3-9
    https://pan.quark.cn/s/6ccab7ec3cbc
  6. 6. 2025年03月份电子学会考级真题
    https://pan.quark.cn/s/4403c4228912
  7. 7. 2025全国青少年信息素养大赛赛项说明
    https://pan.quark.cn/s/d9d0df4a9f29
  8. 8. 青少儿信息素养大赛编程资料
    https://pan.quark.cn/s/4ab6bd83be8a

资料持续更新,关注本号第一时间获取新分享。

抱歉,评论功能暂时关闭!