1 条题解

  • 0
    @ 2026-6-19 10:30:53

    📝 题目大意

    一株植物在第 0 天发芽,高度为 0。第 i 天晚上植物会长高 2^i cm。每天早上高桥君(身高 H cm)与植物比身高,求植物高度首次严格超过 H 是在第几天早上。

    💡 解题思路

    1. 题目分析

      • 约束 H109H \leq 10^9,而 2301.07×1092^{30} \approx 1.07 \times 10^9,因此答案不会超过 30 天,直接模拟完全可行。
      • 关键在于"早上"的高度:第 k 天早上植物高度 = 前 k 天晚上增长的总和,即 20+21++2k1=2k12^0 + 2^1 + \cdots + 2^{k-1} = 2^k - 1
    2. 算法推导

      • 维护两个变量:height 表示当前植物高度(初始为 0),day 表示当前天数(初始为 0)。
      • height <= H 时,说明第 day 天早上植物仍未超过高桥君,需要经历第 day 天晚上的增长:height += 2^day,然后 day++
      • 循环结束时,height > H 成立,此时 day 即为所求的天数。
      • 使用 1LL << day 计算 2day2^{day},避免溢出(虽然 day 最大约 30,但用 long long 更安全)。
    3. 边界与细节

      • 等号处理:题目要求"严格超过",所以 height == H 时仍需继续循环(如样例 2,H=7 时第 3 天早上高度也是 7,不算超过,需等到第 4 天)。
      • 循环条件写为 while (height <= H) 而非 while (height < H),正是为了处理等号情况。
      • 最小输入 H=1 时,第一次循环后 height=1, day=1,此时 1 <= 1,继续循环;height=3, day=2,3 > 1,输出 2。验证:第 1 天早上高度 1,未超过;第 2 天早上高度 3,超过。正确。

    ⏱️ 复杂度分析

    • 时间复杂度O(logH)O(\log H),循环次数不超过 log2(H+1)\lceil \log_2(H+1) \rceil,最多约 30 次。
    • 空间复杂度O(1)O(1),仅使用常数个变量。

    💻 标准代码 (C++)

    #include <iostream>
    using namespace std;
    int main() {
        long long H;
        cin >> H;
        long long height = 0;  // 当前植物高度(早上)
        int day = 0;           // 当前天数
        // 当植物高度还未超过高桥君时,继续生长
        while (height <= H) {
            height += (1LL << day);  // 第 day 天晚上增长 2^day
            day++;                   // 进入下一天早上
        }
        // 循环结束时,height 已经超过 H,day 即为答案
        cout << day << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    800
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者