题解:洛谷 P5743 猴子吃桃

【题目来源】

洛谷:P5743 【深基7.习8】猴子吃桃 - 洛谷(luogu.com.cn)

【题目描述】

一只小猴买了若干个桃子。第一天他刚好吃了这些桃子的一半,又贪嘴多吃了一个;接下来的每一天它都会吃剩余的桃子的一半外加一个。第 \(n\) 天早上起来一看,只剩下 \(1\) 个桃子了。请问小猴买了几个桃子?

【输入】

输入一个正整数 \(n\),表示天数。

【输出】

输出小猴买了多少个桃子。

【输入样例】

4

【输出样例】

22

【核心思想】

  1. 问题分析:猴子每天吃掉当前桃子数的一半再多吃一个,第 \(n\) 天早上醒来时只剩下 1 个桃子。问最初有多少个桃子。这是一个递推/逆推问题,可以通过反向递推解决。

  2. 算法选择

    • 逆推法:第 \(n\) 天剩余 1 个桃子。每天(从第 \(n-1\) 天到第 1 天)的桃子数 \(x\) 满足:当天吃掉 \(\frac{x}{2}+1\) 个,剩余 \(x - (\frac{x}{2}+1) = \frac{x}{2}-1\) 个桃子。因此,若当天剩余 \(r\) 个桃子,则前一天有 \(x = 2 \times (r + 1)\) 个桃子。从第 \(n\) 天剩余 1 个开始,向前递推 \(n-1\) 次即可得到最初的桃子数。
  3. 关键步骤

    • 读入:读取 \(n\)
    • 初始化peach = 1(第 \(n\) 天早上的桃子数)。
    • 逆推循环:重复 \(n-1\) 次:peach = (peach + 1) * 2
    • 输出:输出 peach
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n)\)
    • 空间复杂度:\(O(1)\)
  5. 递推与逆推

    • 逆推公式\(f(i) = 2 \times (f(i+1) + 1)\),其中 \(f(i)\) 表示第 \(i\) 天开始时的桃子数。
    • 终止条件\(f(n) = 1\)
    • 适用场景:这类“正向过程已知,逆向求初始值”的问题,适合用逆推法。

【算法标签】

入门 #模拟

【代码详解】

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

int main()
{
    int n;               // 定义变量:天数n
    int peach = 1;       // 定义变量:初始桃子数量(第n天剩余1个)

    cin >> n;            // 输入天数n

    // 逆向推导第1天的桃子数量
    for (int i = 1; i < n; i++)
    {
        peach += 1;      // 先补回猴子吃掉的那个桃子
        peach *= 2;      // 恢复到前一天的桃子数量(翻倍)
    }

    cout << peach;       // 输出第1天的桃子数量

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

【运行结果】

4
22
posted @ 2026-09-01 09:26  团爸讲算法  阅读(23)  评论(0)    收藏  举报