正在载入在线练习界面,本页内容可直接阅读…

AK CSP › CSP-S 2025 第一轮真题 › 第24题

CSP-S 2025 第一轮 第24题:程序阅读第 2 题 · 第 3 小题

阅读程序·判断 · 模拟与程序跟踪 · 答案 T

题目

#include <algorithm>
#include <cstdio>
#include <cstring>
#define ll long long
int cnt_broken = 0;
int cnt_check = 0;
int n, k;
inline bool check(int h) {
    printf("now check:%d\n", h);
    ++cnt_check;
    if (cnt_broken == 2) {
        printf("You have no egg!\n");
        return false;
    }
    if (h >= k) {
        ++cnt_broken;
        return true;
    } else {
        return false;
    }
}
inline bool assert_ans(int h) {
    if (h == k) {
        printf("You are Right using %d checks\n", cnt_check);
        return true;
    } else {
        printf("Wrong answer!\n");
        return false;
    }
}
inline void guess1(int n) {
    for (int i = 1; i <= n; ++i) {
        if (check(i)) {
            assert_ans(i);
            return;
        }
    }
}
inline void guess2(int n) {
    int w = 0;
    for (w = 1; w * (w + 1) / 2 < n; ++w)
        ;
    for (int ti = w, nh = w;; --ti, nh += ti, nh = std::min(nh, n)) {
        if (check(nh)) {
            for (int j = nh - ti + 1; j < nh; ++j) {
                if (check(j)) {
                    assert_ans(j);
                    return;
                }
            }
            assert_ans(nh);
            return;
        }
    }
}
int main() {
    scanf("%d%d", &n, &k);
    int t;
    scanf("%d", &t);
    if (t == 1) {
        guess1(n);
    } else {
        guess2(n);
    }
    return 0;
}

注意:下述的“猜测数”为调用 check 函数的次数(即 $cnt\_check$ 的值);“猜测正确”的含义为 assert_ans 函数 return true(执行第 25 行所在分支)的情况;所有输入保证 $1 \leq k \leq n$)。

本小题

不管 $t=1$ 或 $t=2$,程序都一定会猜到正确结果。

选项

  • T. 正确
  • F. 错误

答案

T

题解

选 T,正确。

check(h) 在还有鸡蛋时,恰好在 \(h\ge k\) 时返回 true,并摔碎一个鸡蛋。

  • \(t=1\):从 1 开始逐层检查。所有小于 \(k\) 的检查都返回 false,到 \(k\) 时第一次返回 true,随后 assert_ans(k),一定正确。
  • \(t=2\):先按 \(w,w-1,w-2,\ldots\) 的步长向上检查,直到第一次返回 true。由于

\[ 1+2+\cdots+w\ge n, \] 一定能检查到不低于 \(k\) 的位置。

关键是:guess2 第一次在 nh 摔碎鸡蛋后,内层循环会不会漏掉 \(k\)?

设上一次检查的位置为 \(p\)(第一次检查前视为 \(p=0\)),当前步长为 ti,则 \[ p<k\le nh,\qquad nh=\min(p+ti,n). \] 所以内层循环的起点满足 \[ nh-ti+1\le p+1\le k. \] 因此:

  • 若 \(k<nh\),从起点逐层检查必然遇到 \(k\),此时才摔碎第二个鸡蛋,并立即报告正确答案。
  • 若 \(k=nh\),内层检查全部返回 false,最后执行 assert_ans(nh),同样正确。

即使 nh 被截成了 \(n\),也只可能多检查一些已知安全的位置,不会漏掉答案。

真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1 京公网安备11010502062986号