第十四届蓝桥杯 三十天刷题 第六天

文章介绍了使用快速幂解决20的22次方对7取余的问题,以及在考勤刷卡场景下利用TreeSet和TreeMap进行数据去重和排序的Java实现。此外,还讨论了一种卡牌组合优化问题的解法,但未涉及最大子矩阵问题的解答。
摘要由CSDN通过智能技术生成

📢📢📢哈喽哈喽 ~ 我又来了 ,今天没早八,心里乐开花😄😄


  1. 🍓🍓星期计算🍓🍓

📄问题描述

🍓题目很简单就是求20的22次方看对7取余后是多少,就说明在星期六的基础上过了几天,自己口算一下知道是星期几了。群里大佬们用的方法也多种多样,这里我用的是快速幂,这道题当作是我复习快速幂了。

看到的同学也可以学习一下这个快速幂模板,跟着梗佬学的,不是小菜鸡我自己写的嗷😃

📗参考代码

public class Main {
    public static void main(String[] args) {
        long a = qmi(20, 22, 7);
        System.out.println(a);//记得这个输出是指在星期六的基础上过了几天
    }

    //快速幂模板 求a^b%p
    private static long qmi(long a, long b, long p) {
        //这里对p取余是考虑到怕可能为1的情况 如果p为1 那就没有继续下去的必要了
        long res = 1 % p;  
        while (b > 0) {
            //b & 1  就是看b的二进制最后一位是否为1(为1说明b是奇数)是的话b&1结果为1 否则为0
            if ((b & 1) == 1) res = res * a % p; 
            a = (a * a) % p;  //快速幂核心操作——扩底
            b >>= 1;  //快速幂核心操作——降幂
        }
        return res;
    }
}


  1. 🍉🍉考勤刷卡🍉🍉

📄问题描述

❓思路分享

🍉要去重而且排序,我们第一个想到的就是一个数据结构,那就是TreeSet!我们只需要将员工序号分别放到TreeSet里面,然后等待它为我们去重 + 排序咯,不得不说真的是功能强大,太香啦~😍

🍉不过群里大佬还有用TreeMap来实现的,去学习了一下才知道:

TreeMap是一个基于key有序的key value散列表,也就是说TreeMap也可以根据key值来排序。

另外顺便总结了几种遍历输出的方法,在代码中给大家注释了,可以留意一下奥!

📗参考代码

TreeSet实现
import java.io.*;
import java.util.Iterator;
import java.util.TreeSet;


public class 考勤刷卡 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        int n = Integer.parseInt(br.readLine());
        TreeSet<Integer> set = new TreeSet<>();
        for (int i = 0; i < n; i++) {
            String[] s = br.readLine().split(" ");
            set.add(Integer.parseInt(s[1]));
        }
        for (Integer i : set) System.out.println(i);  //增强for遍历
        Iterator<Integer> it = set.iterator();  //使用迭代器 Iterator遍历
        while (it.hasNext()) System.out.println(it.next());
    }
}

TreeMap实现 含map的几种遍历方法
import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class 考勤刷卡_TreeMap {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        int n = Integer.parseInt(br.readLine());
        Map<Integer, String> map = new TreeMap<>();
        for (int i = 0; i < n; i++) {
            String[] s = br.readLine().trim().split(" ");
            String time = s[0];
            int id = Integer.parseInt(s[1]);
            map.put(id,time);
        }
        //增强for循环遍历  底层实现是迭代器
        for(Object i : map.keySet()) System.out.println(i);

        //通过entrySet实现遍历
        Set<Map.Entry<Integer,String>> entrySet = map.entrySet();
        for (Map.Entry entry : entrySet){
            System.out.println(entry.getKey());
        }

        //通过Iterator迭代器实现遍历
        Iterator<Map.Entry<Integer,String>> entryIterator = map.entrySet().iterator();
        while(entryIterator.hasNext()){
            Map.Entry<Integer,String> entry = entryIterator.next();
            System.out.println(entry.getKey());
        }

        //通过lambda表达式实现遍历
        map.forEach((id,time) ->{
            System.out.println(id);
        });
    }
}


  1. 🍅🍅卡牌🍅🍅

📄问题描述

🍅

❓思路分享

🍅题意大概就是一套牌由n种不同的牌组成(1-n),每种牌初始有若干张(ai),也给定了每种牌最多可以添多少张(bi),能添进来牌的总个数也有限制(m),要求出最多可以凑出多少套牌。

🍅🍅假设最多可以凑够x套牌,那么也1到x套牌也是能凑够的,超过x套就凑不够了,这就满足了二段性,后一段是我们不要的,前一段是我们要的。

详细的思路我注释在了代码里面,请移步。👇

📗参考代码

import java.io.*;

public class 卡牌 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static int N = 200010;
    static int[] a = new int[N];
    static int[] b = new int[N];
    static long m, n;

    public static void main(String[] args) throws IOException {
        String[] s = br.readLine().split(" ");
        n = Long.parseLong(s[0]);
        m = Long.parseLong(s[1]);//供添加的卡牌总数量
        s = br.readLine().split(" ");
        for (int i = 1; i <= n; i++) {
            a[i] = Integer.parseInt(s[i - 1]);//i种卡牌初始数量
        }
        s = br.readLine().split(" ");
        for (int i = 1; i <= n; ++i) {
            b[i] = Integer.parseInt(s[i - 1]);//限制添加的最大数量
        }
        int l = 0, r = 2 * N;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            //如果能凑够mid套牌 那么mid作为左边界继续查找最大的可以凑出的卡牌套数
            if (check(mid)) l = mid;
            else r = mid - 1;
        }
        System.out.println(l);
    }

    //判断能否凑够x套牌
    static boolean check(int x) {
        long v = m;
        for (int i = 1; i <= n; ++i) {
            //当第 i 种牌的起始数量已经比我们要尝试的套数大的时候,不用再给这种牌添,跳过
            if (a[i] >= x) continue;
            //当给第i种牌添加了最大限制b[i]张仍不够x时,那么说明x套是凑不成的
            if (a[i] + b[i] < x) return false;
            //能凑够x的情况 并且剩下供添加的卡牌数量足够时 消耗供添加的卡牌数量   否则凑不成
            if (a[i] + b[i] >= x && v >= x - a[i]) v -= (x - a[i]);
            else return false;
        }
        //循环结束 说明i种卡牌都能凑够x张 返回true
        return true;
    }
}


  1. 🍆🍆最大子矩阵🍆🍆

才疏学浅,不会写,等我水平到了一定补上! ✊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值