华为OD机试 - 选举拉票 - 贪心算法(Java 2025 A卷 100分)
·

五、代码
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取选民数量
int n = scanner.nextInt();
// 记录所有选民的投票信息,每个元素是一个长度为2的数组,第一个元素是候选人编号,第二个元素是改变选票的花费
List<int[]> voters = new ArrayList<>();
// 统计各候选人的票数,键是候选人编号,值是票数
Map<Integer, Integer> votes = new HashMap<>();
// 读取每个选民的信息
for (int i = 0; i < n; i++) {
int candidate = scanner.nextInt(); // 选民当前投票给的候选人编号
int cost = scanner.nextInt(); // 让选民改投给我(0号候选人)的花费
// 记录选民信息
voters.add(new int[]{candidate, cost});
// 更新票数统计
votes.put(candidate, votes.getOrDefault(candidate, 0) + 1);
}
// 获取我(0号候选人)的当前票数
int myVotes = votes.getOrDefault(0, 0);
// 检查我是否已经赢得选举,即我的票数严格多于任何其他候选人
boolean alreadyWinning = true;
for (Map.Entry<Integer, Integer> entry : votes.entrySet()) {
// 如果有任何其他候选人的票数大于等于我的票数,那么我还没有赢得选举
if (entry.getKey() != 0 && entry.getValue() >= myVotes) {
alreadyWinning = false;
break;
}
}
// 如果我已经赢得选举,不需要额外花费
if (alreadyWinning) {
System.out.println(0);
return;
}
// 筛选出不投给我的选民,并按照花费排序
List<int[]> otherVoters = new ArrayList<>();
for (int[] voter : voters) {
if (voter[0] != 0) {
otherVoters.add(voter);
}
}
// 按照花费从小到大排序,这样可以优先选择花费小的选民
otherVoters.sort(Comparator.comparingInt(v -> v[1]));
// 记录总花费
int totalCost = 0;
// 复制一份当前的票数情况,用于模拟过程
Map<Integer, Integer> currentVotes = new HashMap<>(votes);
// 模拟说服选民的过程
for (int[] voter : otherVoters) {
int candidate = voter[0]; // 选民当前投票给的候选人
int cost = voter[1]; // 改变这个选民投票的花费
// 更新票数:原候选人减少一票,我增加一票
currentVotes.put(candidate, currentVotes.get(candidate) - 1);
currentVotes.put(0, currentVotes.getOrDefault(0, 0) + 1);
// 增加总花费
totalCost += cost;
// 检查我是否已经赢得选举
boolean isWinning = true;
for (Map.Entry<Integer, Integer> entry : currentVotes.entrySet()) {
// 检查是否有其他候选人的票数大于等于我的票数
if (entry.getKey() != 0 && entry.getValue() >= currentVotes.get(0)) {
isWinning = false;
break;
}
}
// 如果我已经赢得选举,可以停止说服更多的选民
if (isWinning) {
break;
}
}
// 输出最小花费
System.out.println(totalCost);
}
}
更多推荐


所有评论(0)