题意理解
n个苹果从左到右排成一列。每天操作:从第 1 个开始,每隔 2 个拿走 1 个。剩下苹果保持原顺序重新排成新序列。
问两个值:
- 一共多少天拿完全部苹果。
- 原始编号为n的苹果,会在第几天被拿走。
代码拆分
整个代码可以分为两个部分,计算总天数与哪天拿n;
第一部分:总天数
cpp
int x=n;
while(x>0)
{
x-=(x+2)/3;
cnt++;
}
(x+2)/3是计算今天拿走了多少个(x+2是为了向上取整)。
第二部分:哪天拿走n
cpp
int day=0;
while(true)
{
day++;
if(n%3==1)
{
break;
}
n=n-ceil(n/3.0);
}
注意:这里的n不再是原始总苹果数,代表:原始编号为 n 的苹果,在当前这一轮序列里的位置
今天要拿走的是:位置满足pos%3 =1 的苹果。
如果 pos%3 ==1:这个苹果就在今天被拿走,循环结束,day 就是答案。
如果没有被拿走,它会留在序列中,需要计算它下一轮的新位置,继续下一天。
新位置 = 原位置 − 前面被拿走苹果的个数。
完整AC代码
cpp
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
//第一部分:求拿完所有苹果总天数cnt
int x=n;
int cnt=0;
while(x>0)
{
// 本轮拿走ceil(x/3) = (x+2)/3
x -= (x+2)/3;
cnt++;
}
//第二部分:求原始编号n的苹果在哪一天被拿走
int pos=n; // pos:该苹果在当前一轮序列的位置(1‑based)
int day=0;
while(true)
{
day++;
if(pos%3==1) // 当前位置模3等于1,今天被拿走
{
break;
}
//没被拿走,更新为下一轮的位置
pos = pos - ceil(pos / 3.0);
}
cout<<cnt<<" "<<day;
return 0;
}