点击题目连接
题目大意
有 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;
}
总结
本题通过分析灌木的修剪顺序和生长规律,找到了每棵灌木最高高度的数学表达式。通过直接计算而非模拟,大大提高了算法的效率,适合处理大规模数据。