Codeforces Round #618 (Div. 1)C(贪心)

把所有数看作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\n",a[i]);
44     return 0;
45 }

 

posted @ 2020-02-10 21:08  sewage  阅读(174)  评论(0编辑  收藏  举报