题解:洛谷 P5743 猴子吃桃
【题目来源】
洛谷:P5743 【深基7.习8】猴子吃桃 - 洛谷(luogu.com.cn)
【题目描述】
一只小猴买了若干个桃子。第一天他刚好吃了这些桃子的一半,又贪嘴多吃了一个;接下来的每一天它都会吃剩余的桃子的一半外加一个。第 \(n\) 天早上起来一看,只剩下 \(1\) 个桃子了。请问小猴买了几个桃子?
【输入】
输入一个正整数 \(n\),表示天数。
【输出】
输出小猴买了多少个桃子。
【输入样例】
4
【输出样例】
22
【核心思想】
-
问题分析:猴子每天吃掉当前桃子数的一半再多吃一个,第 \(n\) 天早上醒来时只剩下 1 个桃子。问最初有多少个桃子。这是一个递推/逆推问题,可以通过反向递推解决。
-
算法选择:
- 逆推法:第 \(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\) 次即可得到最初的桃子数。
-
关键步骤:
- 读入:读取 \(n\)。
- 初始化:
peach = 1(第 \(n\) 天早上的桃子数)。 - 逆推循环:重复 \(n-1\) 次:
peach = (peach + 1) * 2。 - 输出:输出
peach。
-
时间/空间复杂度:
- 时间复杂度:\(O(n)\)。
- 空间复杂度:\(O(1)\)。
-
递推与逆推:
- 逆推公式:\(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
浙公网安备 33010602011771号