1 条题解

  • 0
    @ 2026-9-6 20:54:56

    星港回执 题解

    题意与关键信息

    • 给定函数
    $$f(x)= \begin{cases} f(f(x+11)), & x \le 100,\\ x-10, & x \ge 101. \end{cases}$$
    • 输入若干行 xx1x1061 \le x \le 10^6,以 00 结束),询问数不超过 2.5×1062.5 \times 10^6,对每个 xx 输出 f(x)f(x)

    从暴力到正解

    朴素递归(x10x \le 10,40 分)

    按定义直接写递归:

    int f(int x) {
        if (x >= 101) return x - 10;
        return f(f(x + 11));
    }
    

    x10x \le 10 时,内层 f(x+11)f(x+11) 的参数不超过 2121,递归深度很浅,直接模拟即可。但当 xx 接近 100100 时,例如 f(100)=f(f(111))f(100)=f(f(111)),内层参数会先跳到 101101 以上再回落,递归过程并不直观——这一档考察的是"照抄定义"的准确性与对递归结构的耐心展开。

    关键观察(无限制,正解)

    先看几个关键值:

    f(111)=101,f(110)=100,,f(101)=91.f(111)=101,\qquad f(110)=100,\dots,f(101)=91.

    x[91,100]x \in [91,100]

    f(x)=f(f(x+11)),f(x)=f(f(x+11)),

    x+11[102,111]x+11 \in [102,111] 已落在 x101x \ge 101 分支,故 f(x+11)=x+1[92,101]f(x+11)=x+1 \in [92,101]

    • x+1=101x+1 = 101(即 x=100x=100),则 f(100)=f(101)=91f(100)=f(101)=91
    • x+1[92,100]x+1 \in [92,100],还需要 f(x+1)f(x+1),而 x+1x+1 仍属于 [91,100][91,100]

    f(100)=91f(100)=91 向上归纳:f(99)=f(100)=91f(99)=f(100)=91f(98)=f(99)=91f(98)=f(99)=91,……得到

    f(x)=91,91x100.f(x)=91,\quad 91 \le x \le 100.

    再向下归纳:若 x90x \le 90,则 x+11[12,101]x+11 \in [12,101]。只要 x+11100x+11 \le 100 就继续套用上面的结论,最终得到

    f(x)=91,1x100.\boxed{f(x)=91,\quad 1 \le x \le 100.}

    (这正是经典的 McCarthy 91 函数。)

    正解

    对每个询问 O(1)O(1) 回答:

    cout << (x >= 101 ? x - 10 : 91) << '\n';
    

    复杂度

    • 每个询问 O(1)O(1),总时间复杂度 O(Q)O(Q),空间 O(1)O(1),其中 QQ 为询问总数(2.5×106\le 2.5\times10^6)。

    易错点

    1. 结束标记:读入遇到 00 立即停止,00 本身不产生输出。
    2. x100x \le 100 不是 x10x-10:只有 x101x \ge 101 才直接减 1010x=100x=100 的答案是 9191 而非 9090
    3. 递归写法可能栈溢出:若把递归写成"先算内层再套外层",对任意 xx 深度都很浅;但若实现有误(例如忘记 f(f(x+11))f(f(x+11)) 的两层调用)会得到错误结果。
    4. 大数据量输入输出:询问数可达 2.5×1062.5\times10^6,务必使用快速 IO(ios::sync_with_stdio(false)getchar 手写读入)。

    参考代码

    summercspj262A.cpp

    • 1

    信息

    ID
    252
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    100
    已通过
    19
    上传者