鱼C论坛

 找回密码
 立即注册
查看: 1940|回复: 2

[已解决]C++关于抽烟问题

[复制链接]
发表于 2023-10-9 17:39:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
要求:
Peter 有 n 根烟,他每吸完一根烟就把烟蒂保存起来,k个烟蒂可以换一个新的烟,那么 Peter 最终能吸到多少根烟呢?

  1. #include<iostream>  
  2. int smoke(int num, int count, int sm) {
  3.         count = num + smoke((num - num % sm) / sm, count, sm);
  4.         return count;
  5. }

  6. int main() {
  7.         using namespace std;
  8.         int num, sm, count = 0;
  9.         cin >> num >> sm;
  10.         smoke(num, count, sm);
  11.         cout << count << endl;
  12. }
复制代码


返回代码为 -1073741571

求大佬解答
最佳答案
2023-10-9 17:39:46
这段代码的问题是在递归调用时,没有考虑到递归结束的情况,导致无限递归,最终导致栈溢出(stack overflow)。

正确的递归实现应该在递归结束的情况下返回结果,例如当 num < sm 时,无法再换新的烟,应该直接返回 count。修改后的代码如下:

  1. #include <iostream>

  2. int smoke(int num, int count, int sm) {
  3.     if (num < sm) {
  4.         return count + num;
  5.     }
  6.     count += num - num % sm;
  7.     return smoke((num - num % sm) / sm + num % sm, count, sm);
  8. }

  9. int main() {
  10.     using namespace std;
  11.     int num, sm, count = 0;
  12.     cin >> num >> sm;
  13.     cout << smoke(num, count, sm) << endl;
  14.     return 0;
  15. }
复制代码


这样就可以正确计算 Peter 最终能吸到多少根烟了。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-10-9 17:39:46 | 显示全部楼层    本楼为最佳答案   
这段代码的问题是在递归调用时,没有考虑到递归结束的情况,导致无限递归,最终导致栈溢出(stack overflow)。

正确的递归实现应该在递归结束的情况下返回结果,例如当 num < sm 时,无法再换新的烟,应该直接返回 count。修改后的代码如下:

  1. #include <iostream>

  2. int smoke(int num, int count, int sm) {
  3.     if (num < sm) {
  4.         return count + num;
  5.     }
  6.     count += num - num % sm;
  7.     return smoke((num - num % sm) / sm + num % sm, count, sm);
  8. }

  9. int main() {
  10.     using namespace std;
  11.     int num, sm, count = 0;
  12.     cin >> num >> sm;
  13.     cout << smoke(num, count, sm) << endl;
  14.     return 0;
  15. }
复制代码


这样就可以正确计算 Peter 最终能吸到多少根烟了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-9 17:41:18 | 显示全部楼层
问题描述:

给定 Peter 有 n 根烟,他每吸完一根烟就把烟蒂保存起来,k 个烟蒂可以换一个新的烟,那么 Peter 最终能吸到多少根烟呢?

问题分析:

这是一个比较经典的递归问题。我们可以写一个递归函数 smoke(num, count, sm),其中 num 表示现在还有 num 根烟,count 表示已经抽了多少根烟,sm 表示 k 个烟蒂可以换一支新的烟。

递归的过程可以这样描述:每当 Peter 抽一根烟时,他会将其烟蒂保存起来。每收集到 k 个烟蒂时,他就可以换一根新的烟来继续抽。因此,递归的终止条件是 num < sm,也就是说,当剩余的烟数小于 k 时,Peter 无法再抽出新的烟。

递归的过程中,每当 Peter 抽完一根烟时,他会将其烟蒂保存起来,并且将抽出的烟的数量加一。然后,他将剩余的烟数减去他抽的这根烟的数量,然后递归调用 smoke 函数来计算他能够获得的额外烟数。最后将额外烟数加到 count 中,并返回 count。

解决方案:

根据以上分析,可以写出代码如下:
  1. ++
  2. #include <iostream>
  3. int smoke(int num, int count, int sm) {
  4.     if (num < sm) {
  5.         return count;
  6.     }
  7.     int new_smoke = num / sm; // 可以换多少个新烟
  8.     int rest_smoke = num % sm; // 剩余的烟蒂
  9.     count += new_smoke; // 将换来的新烟加到 count 中
  10.     return smoke(new_smoke + rest_smoke, count, sm); // 递归
  11. }
  12. int main() {
  13.     int num, sm, count = 0;
  14.     std::cin >> num >> sm;
  15.     std::cout << smoke(num, count, sm) << std::endl;
  16.     return 0;
  17. }
复制代码

在 main 函数中读入 num 和 sm,然后调用 smoke 函数来计算 Peter 最终能吸到的烟的数量,最后输出这个数量即可。

总结:

此题为一个经典的递归问题,通过递归函数来模拟抽烟的过程,可以快速地解决这个问题。递归函数的关键在于理解递归的过程,并且要考虑清楚递归的终止条件是什么。

希望这个解答可以帮助到您!

球一个最佳答案谢谢啦!这对我非常重要!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-9 17:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表