2018年第九屆藍橋杯大學生A組C/C++第十題
阿新 • • 發佈:2019-01-11
描述一下自己:自己沒控制好時間 ,沒有提前練習;
問題描述:
n個人吃飯,總共花費m錢數,n個人分別帶a0,a1,....錢,計算怎麼出錢使得
這n個人出的錢的方差最小。輸出方差即可。
輸入:
10 30
2 1 3 4 5 6 7 8 9 10
輸出:
0.7928
忘了輸入輸出的格式要求,但是可以肯定的是,他說明了一個人出的錢可以不是一分錢的整數倍,就是說,double型別,然後不用考慮人民幣的整數情況。如有疑問 可以留言//藍橋杯2018年第九屆 c/c++ A組演算法 第十題 #include<stdio.h> #include<math.h> #define N 1000 int main(){ int i,j,n,m,coutpoor=0,coutave; double a[N],b[N],ave,sum1=0,temp,sum2=0; scanf("%d %d",&n,&m); ave=m*1.0/n; for(i=0;i<n;i++){ //輸入n個人手上的現金 scanf("%lf",&a[i]); if(a[i]<=ave){ //與此同時將少於平均錢 的 人 挑出來,因為他們必須得傾其所有,使得方差變小 b[coutpoor++]=a[i]; } } for(i=0;i<n;i++) //將他們的錢由小到大排序 for(j=n-1;j>i;j--){ //懶得去寫更高效率的排序演算法了 if(a[j]<a[j-1]){ temp=a[j]; a[j]=a[j-1]; a[j-1]=temp; } } //for(i=0;i<n;i++){ // printf("%lf ",a[i]); //} if(coutpoor==0){ for(i=0;i<n;i++)b[i]=ave; //如果沒有窮人(即大家帶的錢都超過平均),則最終所出的錢放在b[N]中 sum2=0; } else{ for(i=0;i<coutpoor;i++)sum1=sum1+ave-b[i]; //算出 “窮人”總差值 (因為需要後面的人補額) coutave=coutpoor; //我們總是希望讓後面的人儘量 平攤 差額 for(i=coutpoor;i<n;i++){ if(a[i]<(sum1/(n-coutave)+ave)){ //去找補額的人,如果當前人選 不足以 平攤 平均差額 b[i]=a[i]; //交出你所有的錢 sum1=sum1-(a[i]-ave); //雖然不足以平攤平均差額 但是還是填補了空缺 ,此時差額變小 coutave++; //記錄欠 和補 差額的人 } else{ b[i]=sum1/(n-coutave)+ave; //如果 這個人選 “有錢” 則 直 接 補差額 } } for(i=0;i<n;i++){ sum2=sum2+(b[i]-ave)*(b[i]-ave); //計算方差 根號下面的sum } } printf("%.4lf",sqrt(sum2/n)); //最小方差 return 0; }