题解:洛谷 P5720 一尺之棰

【题目来源】

洛谷:P5720 【深基4.例4】一尺之棰 - 洛谷

【题目描述】

《庄子》中说到,“一尺之棰,日取其半,万世不竭”。第一天有一根长度为 \(a\) 的木棍,从第二天开始,每天都要将这根木棍锯掉一半(每次除 \(2\),向下取整)。第几天的时候木棍的长度会变为 \(1\)

【输入】

输入一个正整数 \(a\),表示木棍长度。

【输出】

输出一个正整数,表示要第几天的时候木棍长度会变为 \(1\)

【输入样例】

100

【输出样例】

7

【核心思想】

  1. 问题分析:给定初始木棍长度 \(a\),每天将其锯掉一半(整数除法,向下取整),求第几天长度变为 \(1\)。这是一个模拟折半过程的问题。

  2. 算法选择

    • 循环折半模拟:每天执行 \(a = a / 2\)(整数除法),同时天数计数器累加,直到 \(a = 1\)
  3. 关键步骤

    • 读入数据cin >> a
    • 初始化day = 1(第一天已有长度 \(a\)
    • 循环折半(当 a != 1):
      • a /= 2:长度减半(整数除法自动向下取整)
      • day++:天数加 1
    • 输出结果day
  4. 时间/空间复杂度

    • 时间复杂度:\(O(\log a)\),每次循环 \(a\) 减半,最多循环 \(\log_2 a\)
    • 空间复杂度:\(O(1)\),仅需两个变量
  5. 折半模拟的核心思想

    • 整数除法特性:C++ 中 a /= 2 对整数自动向下取整,恰好符合"锯掉一半"的要求
    • 天数计数:从第 1 天开始计数,每次折半后进入下一天,确保最终天数包含达到 1 的那一天
    • 对数级效率\(a\) 每次减半,循环次数与 \(a\) 的大小成对数关系,效率极高
    • 适用于折半递推、对数级模拟、过程追踪类入门问题

【算法标签】

入门 #模拟

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件(万能头文件)
using namespace std;      // 使用标准命名空间

/**
 * 主函数 - 程序入口
 * @return 程序执行状态码(0表示成功)
 */
int main()
{
    int a;               // 定义变量:初始a
    int day = 1;         // 定义变量:天数计数器,初始为1

    cin >> a;            // 输入初始

    // 模拟细胞分裂过程(每天数量减半)
    while (a != 1)       // 当数量不为1时继续循环
    {
        a /= 2;          // 数量减半(整数除法)
        day++;           // 天数加1
    }

    cout << day;         // 输出总天数

    return 0;            // 程序正常结束
}

【运行结果】

100
7
posted @ 2026-08-05 15:47  团爸讲算法  阅读(23)  评论(0)    收藏  举报