题目描述

2018蓝桥杯省赛---java---A---10(付账问题)_算法
2018蓝桥杯省赛---java---A---10(付账问题)_算法_02

思路分析

用贪心算法,要使标准差最小,则需要将每个人需付的钱接近于平均值。如果有人的钱低于当前平均值a1,则需要将这人的钱全部支付,此人不够的钱需让其他人付,然后可以计算剩余人所需付钱的平均值a2,此时平均值会被拉高,a2会大于a1,此时可能又有人的钱低于当前的平均值a2,再次按上个步骤,再计算出新的平均值a3,…直到剩余的人的钱都大于当前的平均值ai,那么这一部分人所付的钱都为这个平均值ai。

代码实现
package lanqiao;

import java.util.Collections;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int n,s,a=0;
        double ave=0,sum=0.0;
        n=in.nextInt();     //总人数
        s=in.nextInt();  //总金额
        int c[]=new int[n];
        for(int i=0;i<n;i++) {
            c[i]=in.nextInt();
        }
        ave=(double)s/n;//开始时的平均数
        double ave1=ave;
        for(int i=0;i<c.length-1;i++)  //排序
            for(int j=i+1;j<c.length;j++) {
                if(c[i]>c[j]) {
                    int temp=c[i];
                    c[i]=c[j];
                    c[j]=temp;
                }
            }


        //贪心算法
        for(int i=0;i<n;i++) {
            if(c[i]<ave1) {//ave1不断变化的平均数
                sum+=(c[i]-ave)*(c[i]-ave);
                s-=c[i];
                ave1=(double)s/(n-i-1);
            }else {
                sum+=(ave1-ave)*(ave1-ave);
            }
        }
        System.out.println(String.format("%.4f", Math.sqrt(sum/n)));
    }
}

2018蓝桥杯省赛---java---A---10(付账问题)_java_03