P9748 [CSP-J 2023] 小苹果-----又爱又恨的小苹果!!!

# [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
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
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;
}

这串代码通过了,大家可以自己领悟一下。

所以这道题解出来了吗?你爱了吗?!

你可能感兴趣的:(算法)