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

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

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

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

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为初始的苹果数量。在具体问题中,可以根据实际情况选择合适的方法进行求解。