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

猜你喜欢

转载自blog.csdn.net/sinat_33472635/article/details/79824266
今日推荐