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

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


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).总结

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

试题链接:

相关推荐
罗湖老棍子19 分钟前
C Looooops(信息学奥赛一本通- P1640)
算法·数论·同余·裴蜀定理·扩展欧几里得
飘尘3 小时前
从"算子"到"AI Infra":大模型背后看不见的那群人在忙什么
人工智能·算法·面试
夏幻灵3 小时前
每日一题:LeetCode 3:无重复字符的最长子串——滑动窗口思路详解
算法·leetcode·职场和发展
CarIise4 小时前
Java实训阶段查漏补缺复习笔记2
java·linux·算法
无忧.芙桃4 小时前
C++ 并查集详解:原理、实现与应用
c语言·c++·算法·leetcode
蛋蛋的就会顺顺的4 小时前
hot100——二叉树
java·数据结构·算法·leetcode·力扣
Code_Solitude5 小时前
c语言:二分法的完整补充
c语言·开发语言·算法
一切皆是因缘际会5 小时前
掌控信息论:同源星际通信基础理论
人工智能·算法·ai
智者知已应修善业5 小时前
【51单片机只有一个8*8点阵数据如何滚动起来一片595+一组IO+花样】2022-1-15
c++·经验分享·笔记·单片机·蓝桥杯·硬件架构
动词ing7 小时前
【C语言题目练习】算法 整数反转
c语言·开发语言·算法