题解来源: 上外三亚附中 周林甫 老师 发表于公众号《科创学习》欢迎大家关注。

这道题目主要考察了字符串处理和模拟算法。需要对输入的字符串进行分割和处理,同时模拟苹果的分配过程。类似“猴子选大王”的项目

字符串处理:对输入的字符串进行分割、提取关键信息等操作。

模拟算法:根据题目要求,按照规则模拟苹果的分配过程,并计算最终每个人分到的苹果数量。

image.png

使用两种方法来解决这个问题

方法1:非递归方法

首先定义变量n表示初始的苹果数量,ans表示总的轮数,k表示记录第一次选中最后一个的轮数。

使用while循环,当n不为0时进行处理。

每轮处理,轮数ans加1。

如果(n-1)能被3整除且k为0,表示选中最后一个,记录第一次选中最后一个的轮数为k。

更新苹果数量,每次减去(n-1)/3+1个苹果。

输出总的轮数ans和第一次选中最后一个的轮数k。

  
#include <iostream>  
using namespace std;  
  
int main() {  
    int n, ans = 0, k = 0;  
    // 初始化输入值、轮数、以及记录第一次选中最后一个的变量  
    cin >> n;  // 输入初始的苹果数量  
    while (n) {  
        ans++;  // 每轮处理,轮数加1  
        if ((n - 1) % 3 == 0 && k == 0) {  
            // 如果 (n-1) 能被 3 整除,且 k 为 0,表示选中最后一个  
            k = ans;  // 记录第一次选中最后一个的轮数  
        }  
        n = n - ((n - 1) / 3 + 1);  
        // 更新苹果数量,每次减去 (n-1)/3+1 个苹果  
    }  
    cout << ans << " " << k;  
    // 输出总的轮数和第一次选中最后一个的轮数  
    return 0;  
}  

方法2:递归方法

定义函数pick,参数n表示剩余的苹果数量,返回值为被拿走的苹果个数。

如果最后一个苹果编号n%3等于1,表示本轮被拿走,返回1。

否则,递归调用pick函数,传入n-(n+2)/3作为参数,并将返回结果加1。

在主函数中,读入n表示初始的苹果数量。

调用pick函数计算被拿走的苹果个数,将结果赋给ans。

使用while循环,当n不为0时进行处理。

每轮处理,轮数ans加1。

更新苹果数量,每次减去(apple+2)/3个苹果。

输出总的轮数ans和第一次选中最后一个的轮数pick(n)。

  
#include<bits/stdc++.h>  
using namespace std;  
  
int pick(int n) {  
    if (n % 3 == 1)  
        return 1;  
    return pick(n - (n + 2) / 3) + 1;  
}  
  
int main() {  
    int n, ans = 0;  
    cin >> n;  // 输入初始的苹果数量  
    ans = pick(n);  
    cout << ans << " " << pick(n) << endl;  
    // 输出总的轮数和第一次选中最后一个的轮数  
    return 0;  
}  

这两种方法都是基于问题的规律进行求解,通过不断迭代计算得到结果。方法1使用非递归的方式,每次循环更新苹果数量,直到苹果数量为0。方法2使用递归的方式,根据问题的规律进行递归计算,直到满足基线出口条件。两种方法的时间复杂度都是O(logn),其中n为初始的苹果数量。在具体问题中,可以根据实际情况选择合适的方法进行求解。