首页 > 试题广场 >

小红闯关

[编程题]小红闯关
  • 热度指数:4420 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\,\,\,\,\,\,\,\,\,\,小红在玩一个游戏,这个游戏有 n 个关卡,通过第 i 个关卡需要消耗 a_i 个单位时间,小红必须按从前往后的顺序通过每一个关卡。
\,\,\,\,\,\,\,\,\,\,每通过 k 个关卡,小红会获得一个跳关道具,跳关道具可以在任意一个关卡使用,使用跳关道具后可以不消耗时间直接通过关卡。
\,\,\,\,\,\,\,\,\,\,小红想知道她通过这 n 个关卡,最少需要多少时间。

输入描述:
\,\,\,\,\,\,\,\,\,\,第一行输入两个整数 n, k\left(1 \leq n, k \leq 10^5\right) 代表关卡数量和获得跳关道具的条件。
\,\,\,\,\,\,\,\,\,\,第二行输入 n 个整数 a_1, a_2, \dots, a_n\left(1 \leq a_i \leq 10^5\right) 代表通过每个关卡需要消耗的时间。


输出描述:
\,\,\,\,\,\,\,\,\,\,在一行上输出一个整数,表示小红通过这 n 个关卡所需的最少时间。
示例1

输入

3 2
1 3 2

输出

4

说明

\,\,\,\,\,\,\,\,\,\,小红通过第二个关卡后获得跳关道具,此时消耗 1+3 单位时间;在第三个关卡使用跳关道具,不再消耗时间。
示例2

输入

6 2
1 1 4 5 1 4

输出

7

说明

\,\,\,\,\,\,\,\,\,\,小红通过第二个关卡后获得第一个跳关道具;
\,\,\,\,\,\,\,\,\,\,在第四个关卡使用第一个跳关道具后得到第二个跳关道具;
\,\,\,\,\,\,\,\,\,\,在第六个关卡使用第二个跳关道具。
示例3

输入

5 1
2 4 5 1 3

输出

2

说明

\,\,\,\,\,\,\,\,\,\,通过第一关后,后面的关卡都可以使用跳关道具。跳关也算一次成功的闯关。
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int k = scanner.nextInt();

        int[] times = new int[n];
        for (int i = 0; i < n; i++) {
            times[i] = scanner.nextInt();
        }

        // 计算能获得的跳关道具数量
        int props = n / k;

        // 如果没有道具,直接返回所有关卡时间总和
        if (props == 0) {
            long sum = 0;
            for (int time : times) {
                sum += time;
            }
            System.out.println(sum);
            return;
        }

        // 使用小顶堆来保存我们要跳过的最大时间关卡
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();

        long totalSum = 0;

        for (int i = 0; i < n; i++) {
            totalSum += times[i];

            // 记录当前已获得的道具数量 (到第i+1关为止)
            int currentProps = i / k;

            // 如果当前已获得的道具数量多于堆的大小,说明刚获得了新道具
            if (currentProps > minHeap.size()) {
                minHeap.add(times[i]);
            }
            // 如果已经获得了道具,且当前关卡时间比堆中最小的要大,则替换
            else if (currentProps > 0 && times[i] > minHeap.peek()) {
                minHeap.poll();
                minHeap.add(times[i]);
            }
        }

        // 计算需要减去的总时间(被跳过的关卡)
        long skipSum = 0;
        while (!minHeap.isEmpty()) {
            skipSum += minHeap.poll();
        }

        System.out.println(totalSum - skipSum);
    }
}

发表于 2025-09-04 21:32:45 回复(0)