点击题目连接

题目大意

有 n 棵灌木排成一排,每天傍晚爱丽丝会修剪一棵灌木,使其高度变为 0 厘米。修剪顺序是从左到右,再从右到左循环进行。灌木每天早上到傍晚会长高 1 厘米,其余时间不长高。所有灌木在第一天早晨高度为 0 厘米。要求计算每棵灌木最高能长到多少厘米。

输入格式

一个正整数 N ,含义如题面所述。

输出格式

输出 N 行, 每行一个整数, 第行表示从左到右第 i 棵树最高能长到多高。

输入输出样例

输入 #1

3

输出 #1

4
2
4

说明/提示

对于 30% 的数据, N≤10.

对于 100% 的数据, 1<N≤10000.

解题思路

  • 分析灌木的修剪顺序

爱丽丝修剪灌木的顺序是:从左到右修剪一遍,然后从右到左修剪一遍,如此循环。对于 n 棵灌木,其修剪顺序如下:

- 顺序为 1, 2, 3, ..., n, n, n-1, n-2, ..., 1, 1, 2, ..., 以此类推。

  • 灌木的生长与修剪时机

每棵灌木在被修剪的前一天傍晚会被修剪,之后在第二天早上到傍晚长高。因此,每棵灌木的最高高度等于它在被修剪后到再次被修剪前的生长天数

  • 数学推导

通过分析,可以发现每棵灌木的最高高度与其位置有关。对于第 i 棵灌木(1 ≤ i ≤ n),其最高高度可以通过以下方式计算:

- 对于对称位置的两棵灌木(如第 i 棵和第 n-i+1 棵),它们的最高高度是相同的。

- 中间的灌木(当 n 为奇数时)需要单独处理。

具体公式为:

- 当 i ≤ n/2 时,最高高度为 (n - i) * 2。

- 当 i > n/2 时,最高高度与对称位置的灌木相同。

- 当 n 为奇数时,最中间的灌木最高高度为 (n - (n/2 + 1)) * 2。

  •  算法实现

根据上述推导,我们可以直接计算每棵灌木的最高高度,而无需模拟整个过程。这样可以将时间复杂度降低到 O(n),非常适合处理较大的 n 值。

代码实现

#include <bits/stdc++.h>
using namespace std;
int a[10005] = {0};
int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n / 2; ++i) {
        a[i] = (n - i) * 2;
        a[n - i + 1] = (n - i) * 2;
    }
    if (n % 2 != 0) {
        a[n / 2 + 1] = (n - (n / 2 + 1)) * 2;
    }
    for (int i = 1; i <= n; ++i) {
        cout << a[i] << endl;
    }
    return 0;
}

总结

本题通过分析灌木的修剪顺序和生长规律,找到了每棵灌木最高高度的数学表达式。通过直接计算而非模拟,大大提高了算法的效率,适合处理大规模数据。