1. 程式人生 > >2018年第九屆藍橋杯大學生A組C/C++第十題

2018年第九屆藍橋杯大學生A組C/C++第十題

描述一下自己:自己沒控制好時間 ,沒有提前練習;

問題描述:

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;		
} 
如有疑問 可以留言