把所有数看作N块,后面的块比前面的块小的话就合并,这个过程可能会有很多次,因为后面合并后会把前面的块均摊地更小,可能会影响更前面地块,像是多米诺骨牌效应,从后向前推
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 double a[1000007]; 5 vector<double>vv[1000007]; 6 int main(){ 7 //ios::sync_with_stdio(false); 8 //cin.tie(NULL); 9 //cout.tie(NULL); 10 int n; 11 scanf("%d",&n); 12 int mx=n; 13 for(int i=1;i<=n;++i){//初始把n个数字分为n块 14 scanf("%lf",&a[i]); 15 vv[i].emplace_back(a[i]); 16 } 17 while(1){ 18 int flag=0,temp=0; 19 for(int i=1;i<=mx;++i){ 20 double sum=0; 21 for(int j=0;j<vv[i].size();++j) 22 sum+=vv[i][j];//记录第i块的和 23 for(int j=0;j<vv[i].size();++j){ 24 ++temp; 25 a[temp]=sum/vv[i].size();//将第i块均分 26 if((1e-10)+a[temp]<a[temp-1])//这一块的均值小于前一块,则可以继续从后向前合并 27 flag=1; 28 } 29 vv[i].clear(); 30 } 31 if(flag==0)//数组a已经是非降序列 32 break; 33 int tot=0; 34 vv[++tot].emplace_back(a[1]); 35 for(int i=2;i<=n;++i){ 36 if((1e-10)+vv[tot].back()<a[i])//后面比前面小的话就合并到前面的块里,否则不合并 37 ++tot; 38 vv[tot].emplace_back(a[i]); 39 } 40 mx=tot;//合并后剩余的块数,同一块里a数组的值都相同 41 } 42 for(int i=1;i<=n;++i) 43 printf("%.15f ",a[i]); 44 return 0; 45 }