先看N为3的情况下,第一棵树最高可以长多高。我们可以用圆圈表示树把它们一排画在纸上。
可知第二天开始从第二棵树向右剪,再向左剪回到第二棵树的位置上时,第一颗树长到了3厘米,接下来的一天第一棵树先长了1cm,后被剪掉,所以最高可以长到(3+1)=4厘米。
同理,再看第三棵树,最高也可以长到4cm。
(图左:数字表示第一棵树从剪后第一天起,直到再次被剪掉的那天所生长的高度、圆圈代表了一棵树....、数字写在圆圈下表明了对应的树被剪掉的那天第一棵树所能长到的高度。图右同理。)
紧接着对4、5棵树的情况下第一棵树最高可以长到多高。观察一下,不难发现 第一棵树和最后一棵树的 h =(总棵树-1)*2
6 =(4-1)*2 8 =(5-1)*2
第二棵树相比第一棵树,可以选择先向左剪和先向右剪,可以知道向树多的一侧剪再剪回来时需要的天数更多,树也就会长得更高。此时第二棵树向右剪比第一棵树向右剪 少了对自己这棵树剪的两次(虚线方框)。所以 奇数棵树时:最中间树的左侧 从左向右的第 i+1 棵树比第 i 棵树的最高高度少了2厘米。(若是偶数棵树则是左半边的树 从左向右的第 i+1 棵树比第 i 棵树的最高高度少了2厘米)
先从左剪到右,再掉方向剪到左 和 另一棵关于中心对称的树 先从右剪到左,再掉方向剪到右,他们长的最大高度是一样的。所以对最中间的树对称的树长到的最高高度是一样的。对称性就出来了。
对称性出来后,对于偶数棵树知道左边一半后可以两边都求出,但是奇数棵树时,最中间的树就会成为特殊情况。列举发现 奇数棵树时最中间的树的最大高度 =(总棵树-1)
(此时圆圈下的数字代表对应树最高可以长到多高)
更直观的感受下规律:
代码如下:
#include<iostream>
using namespace std;
int a[10100]; //建一个数组存放每棵树的最高高度
int main(){
int n;
cin>>n; //读入树的棵树
for(int i=1;i<=n/2;i++){
a[i]=2*(n-i); //依次存放左半边每棵树的最高高度
a[n-i+1]=a[i]; } //每存放一个左半边树的最高高度时,
//根据对称性同时将右半边对于最中间树对称的树的高度存入
if(n%2!=0) //奇数棵时将最中间的树的高度存入
a[n/2+1]=n-1;
for(int j=1;j<=n;j++)
cout<<a[j]<<endl; //输出
return 0;
}
输出:
感谢观看,如有错误敬请指正。