【问题描述】
有一个长度为n的数组(n是10的倍数),每个数 Ai 都是区间[0,9]中的整数,小明发现数组里每种数出现的次数不太平均,而更改第 i 个数的代价为bi,他想更改着若干个数的值使得这 10 种数出现的次数相等(都等于n/10,请问代价和最少为多少。
【输入格式】
输入的第一行包含一个正整数 n。
接下来n行,第i行包含两个整数ai,bi,用一个空格分隔。
【输出格式】
输出一行包含一个正整数表示答案。
【样例输入】
10
1 1
1 2
1 3
2 4
2 5
2 6
3 7
3 8
3 9
4 10
【样例输出】
27
【样例说明】
只更改第 1,2,4,5.7,8 个数,需要花费代价 1+2+4+5+7+8=27。
【评测用例规模与约定】
对于20%的评测用例,n<=1000;
对于所有评测用例n <= 100000,0<bi<=2×10^5。
java
import java.util.*;
public class Main {
public static void main(String[] args) {
// 创建Scanner对象以读取输入
Scanner sc = new Scanner(System.in);
// 读取第一个整数n,表示后续将有n个整数对
int n = sc.nextInt();
// 计算k值,每个分类需要忽略的最大数值数量(取整)
int k = n / 10;
// 创建一个HashMap,键为分类标签(0-9),值为该分类下的数值列表
HashMap<Integer, ArrayList<Integer>> hm = new HashMap<>();
// 初始化HashMap,为每个分类标签创建一个空的ArrayList
for (int i = 0; i < 10; i++) {
hm.put(i, new ArrayList<>());
}
// 读取n个整数对,并将数值添加到对应分类的列表中
for (int i = 0; i < n; i++) {
int label = sc.nextInt(); // 分类标签
int value = sc.nextInt(); // 数值
hm.get(label).add(value); // 将数值添加到对应分类的列表中
}
// 初始化结果变量
int ans = 0;
// 遍历每个分类,并处理其数值列表
for (int i = 0; i < 10; i++) {
// 获取当前分类的数值列表
ArrayList<Integer> values = hm.get(i);
// 对数值列表进行排序
Collections.sort(values);
// 计算需要累加的数值数量(列表大小减去k)
int m = values.size() - k;
// 累加最小的m个数值到结果变量中
for (int j = 0; j < m; j++) {
ans += values.get(j);
}
}
// 输出结果
System.out.println(ans);
// 关闭Scanner
sc.close();
}
}