#题目#
# [CSP-J 2023] 小苹果【民间数据】
## 题目描述
小 Y 的桌子上放着 n 个苹果从左到右排成一列,编号为从 1 到 n。
小苞是小 Y 的好朋友,每天她都会从中拿走一些苹果。
每天在拿的时候,小苞都是从左侧第 1 个苹果开始、每隔 2个苹果拿走 1 个苹果。随后小苞会将剩下的苹果按原先的顺序重新排成一列。
小苞想知道,多少天能拿完所有的苹果,而编号为 n 的苹果是在第几天被拿走的?
## 输入格式
输入的第一行包含一个正整数 $n$,表示苹果的总数。
## 输出格式
输出一行包含两个正整数,两个整数之间由一个空格隔开,分别表示小苞拿走所有苹果所需的天数以及拿走编号为 $n$ 的苹果是在第几天。
## 样例 #1
### 样例输入 #1
8
### 样例输出 #1
5 5
## 提示
**【样例 $1$ 解释】**
小苞的桌上一共放了 8个苹果。
小苞第一天拿走了编号为 1、4、7 的苹果。
小苞第二天拿走了编号为 2、6的苹果。
小苞第三天拿走了编号为 3 的苹果。
小苞第四天拿走了编号为 5 的苹果。
小苞第五天拿走了编号为 8 的苹果。
#代码一#
超时咯!!
-
#include<bits/stdc++.h> using namespace std; int m[100000005];//储存苹果位置 int n; int main(){ int i,j,t,d=0,f=0,o=0; //d为取苹果的天数 //t为第n位拿走的天数 //f测试点,判断是不是在剩余三天之前拿走第n位的 //o控制位置 cin>>n; for(i=1;i<=n;i++){ m[i]=1; } for(i=1;i<=n;i++){//从1找到n if(m[i]!=0){//如果第i位不为0,说明没拿走 d++;//天数加1 for(j=i;j<=n;j++){//循环从第i位开始 if(m[j]!=0){//如果第j位不为0,位置加一 o++; } if(o==4){//当位置为4时说明该位置需要被拿走 m[j]=0;//将第j位拿走 if(j==n&&f==0){ //判断如果第j位为n 并且f为0(f用来防止重复加天数) //则说明这是第一次取第n位的苹果 t=d;//取走苹果的天数为当前天数 f=1;//改变f,说明第n位已经被取走 } o=1;//拿走该位置苹果后将位置归为1; } m[i]=0; //令第i位为0,因为当天第一个位置o不为4,但是也需要取走 } o=0; //进入下一天的时候,将o归0,因为下一天第一个取的位置一定有苹果 } } if(f==0){//判断第n位的苹果是否在之前就被取走 t=d;//如果没有被取走,说明之前的天数中,第n位一直有苹果 } for(i=1;i<=n;i++){ //遍历一遍,因为之前取苹果还剩下三个苹果无法取掉 if(m[i]!=0){ //如果第i位不为0,则需要多一天取 d++; if(m[n]!=0){ //判断第n位是否被取走,如果没有被取走,则天数加一 t++; } } } cout<<d<<" "<<t; return 0; }
#代码二
AC版
-
#include<bits/stdc++.h> using namespace std; int n; int main(){ int i,j; int d=0,t; int f=0; cin>>n; j=n; while(j-1>=0){ d++; if(j%3==1&&f==0){ t=d; f=1; } if(j%3==0){ j=j-j/3; } else{ j=j-j/3-1; } } cout<<d<<" "<<t; return 0; }