# [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$ 的苹果。 ?
**【样例 $2$】**
见选手目录下的 apple/apple2.in 与 apple/apple2.ans。
当我们看到这道题时,你会先怎么想?(我先来说说我吧,我以为这题是规律题,就像water problem那题一样,但是我想了好久好久没找到规律,然后动笔算了一下,发现没有很特别的规律),所以只能一步一步思考来解答。
开始讲解啦.
首先,我们再没找到规律的情况下,我门其实可以在看到题目的一眼,就发现第一天,拿走的苹果都是1+3*n,这就是第一步。
有了第一步,我们接着思考,那后面几天又跟第一步的表达式有什么关系呢?其实题目就告诉我们了,之后把剩余重新紧密排列在一起,所以排列后拿走苹果的编号还是第一步得到的方程,所以我们用总苹果数——拿走苹果树=下次排列的总苹果数,用几个变量记录一下就好了这就是第二步,也是最后一步。
现在先上我第一次写的代码(90分):
#include<stdio.h>
int main() {
int n,b=1, z = 0;
int arr[10005] = { 0 }, brr[52000] = {0};
scanf("%d", &n);
for (int i = 0;i < n;i++) {
arr[i] = 1;
}
while (arr[0] == 1) {
int y = 0, x = 0;
for (int i = 0;i < n;i = 3*x) {
arr[i] = 0;
x++;
}
if (arr[n - 1] != 0) {
b++;
}
else {
brr[b] = b;
}
n = n - x;
for (int i = 0;i < n;i++) {
arr[i] = 1;
}
z++;
}
b = 0;
printf("%d ", z);
while (brr[b] == 0) {
b++;
}
printf("%d", brr[b]);
return 0;
}
这段代码之所以得90分就是第十个点RE了,因为数组的大小不够。所以我们不用这种方法,换一种方法。
#include<stdio.h>
int main() {
int n, b = 0, z = 1, arr[1005] = {0},y=0;
scanf("%d", &n);
while(n){
if ((n - 1)%3!= 0) {
z++;
}
else {
arr[y] = z;
y++;
}
if ((n-1)/3 >= 1) {
n = n-(n-1)/3-1;
}
else n--;
b++;
}
printf("%d %d", b, arr[0]);
return 0;
}
这串代码通过了,大家可以自己领悟一下。
所以这道题解出来了吗?你爱了吗?!