五、代码

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);
    }
}

 

更多推荐