蓝桥杯P3179——平均

题目 3179: 蓝桥杯2023年第十四届省赛真题-平均

题目描述
有一个长度为 n 的数组(n 是 10 的倍数),每个数 ai 都是区间 [0, 9] 中的整数。小明发现数组里每种数出现的次数不太平均,而更改第 i 个数的代价为bi,他想更改若干个数的值使得这 10 种数出现的次数相等(都等于n/10),请问代价和最少为多少。

解题思路分析

目的:
更改若干个数的值,使给出的数,出现的次数相等(都等于n/10),求更改的这些数需要的最少代价和。

思路:
求出相等的次数,既每个数应出现多少次 = n ➗ 10 ,我们记为平均出现次数
读入每个数 a i a_i ai 和 它的代价 b i b_i bi
统计每个数出现的次数,用数组counts保存起来
遍历数组counts,当找到一个数的 出现次数 > 平均出现次数 时,则表示要更改这个数
优先更改代价较低的数,并将更改的那个数的代价相加,循环次数 = 该数的出现次数 - 平均出现次数

代码实现

   public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        // 存放每个数字出现的次数
        int[] counts = new int[n];
        // 存放数字,和该数字对应的所有代价
        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            // 读入数字和代价
            int num = sc.nextInt();
            int q = sc.nextInt();
            if (!map.containsKey(num))
                map.put(num, new ArrayList<>());
            map.get(num).add(q);
            counts[num]++;// 统计每个数字输入次数
        }
        // 输出的总代价
        int total = 0;
        // 每种数字应该出现的次数(平均出现次数)
        int avg = n / 10;
        for (int i = 0; i < n; i++) {
            // 找出 出现次数 > 平均出现次数 的数
            if (counts[i] > avg) {
                // 找到该数字对应的代价列表
                List<Integer> qs = map.get(i);
                // 对代价进行排序
                Collections.sort(qs);
                // 取前面几个小的代价相加
                for (int j = 0; counts[i] > avg; j++) {
                    total += qs.get(j);
                    counts[i]--;
                }
            }
        }
        System.out.println(total);
    }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值