蓝桥杯双周赛算法心得——通关(哈希+小根堆)

大家好,我是晴天学长,这是很重要的贪心思维题,哈希的存法和小根堆的表示很重要。


1) .通关


2) .算法思路

通关

用hash(int[])存点的子节点并按输入顺序存关卡的号码(输入顺序就是)

列如:key:父节点

难度 经验 关卡

优先队列存难度和节点

1.接受数据和初始经验。(用快读)。

2.判断第1关能过不。

3.把第1关的子节点放入队列

4.从队列中取出元素

5.挑战成功再把子元素丢入队列中

6.ans++;


3).算法步骤

1.从输入中读取关卡数量 n 和初始经验值 sum。

2.读取第一关的难度、关卡和经验值,并将其存储在map中。

3.如果初始经验值小于第一关的经验值要求,则输出0并返回。

4.增加初始经验值并增加答案计数器。

5.循环读取剩余的关卡信息,并将其存储在map中。

6.创建一个小顶堆(优先队列)queue,并将第一关的子节点放入小顶堆。

7.循环处理小顶堆中的关卡节点,直到小顶堆为空。

8.从小顶堆中取出一个关卡节点,比较当前经验值是否小于关卡节点的难度要求,如果是,则输出答案计数器并返回。

9.增加经验值并增加答案计数器。

10.如果当前关卡有子节点,则将子节点放入小顶堆。

11.输出最终的答案计数器。


4). 代码实例

java 复制代码
package LanQiaoTest.大小堆;

import java.util.*;

//变种广搜
public class 通关_小顶堆 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Map<Integer, List<int[]>> map = new HashMap<>();
        //关卡
        int ans = 0;
        int n = scanner.nextInt();
        //经验值
        int sum = scanner.nextInt();
        //存第一关
        int temp = scanner.nextInt();
        int temp1 = scanner.nextInt();
        int temp2 = scanner.nextInt();
        map.put(temp, new ArrayList<>());
        map.get(temp).add(new int[]{0, temp1, temp2});

        int[] temp3 = map.get(temp).get(0);
        if (sum < temp3[2]) {
            System.out.println(ans);
            return;
        }
        sum += temp3[1];
        ans++;
        //存子节点了
        for (int i = 1; i < n; i++) {
            //父节点
            int a = scanner.nextInt();
            //挑战成功的经验值
            int b = scanner.nextInt();
            //难度
            int c = scanner.nextInt();
            if (!map.containsKey(a)) {
                map.put(a, new ArrayList<>());
            }
            //父节点        难度 关卡 经验值
            map.get(a).add(new int[]{c, i + 1, b});
        }
        //用优先队列(默认小根堆)
        PriorityQueue<Integer[]> queue = new PriorityQueue<>((a, b) -> (a[0] - b[0]));
        //把第一关的子节点丢入小根堆
        for (int i = 0; i < map.get(1).size(); i++) {
            int[] temp4 = map.get(1).get(i);
            //难度 关卡 经验值
            queue.offer(new Integer[]{temp4[0], temp4[1], temp4[2]});
        }
        // 开始闯关
        while (!queue.isEmpty()) {
            //难度 关卡 经验值
            Integer[] temp5 = queue.poll();
            //对比
            if (sum < temp5[0]) {
                System.out.println(ans);
                return;
            }
            sum += temp5[2];
            ans++;
            //把闯的关的子节点丢入小根堆
            if (map.containsKey(temp5[1])) {
                for (int i = 0; i < map.get(temp5[1]).size(); i++) {
                    int[] temp6 = map.get(temp5[1]).get(i);
                    queue.offer(new Integer[]{temp6[0], temp6[1], temp6[2]});
                }
            }
        }
        System.out.println(ans);
        scanner.close();
    }
}

4).总结

  • 小根堆的表示(在贪心题中经常使用)
  • 哈希表的正确使用。

试题链接:

相关推荐
浮生如梦_2 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
励志成为嵌入式工程师4 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉4 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer4 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
wheeldown5 小时前
【数据结构】选择排序
数据结构·算法·排序算法
观音山保我别报错6 小时前
C语言扫雷小游戏
c语言·开发语言·算法
TangKenny7 小时前
计算网络信号
java·算法·华为
景鹤7 小时前
【算法】递归+深搜:814.二叉树剪枝
算法
iiFrankie7 小时前
SCNU习题 总结与复习
算法
Dola_Pan8 小时前
C++算法和竞赛:哈希算法、动态规划DP算法、贪心算法、博弈算法
c++·算法·哈希算法