【2020年蓝桥杯Java-B组省赛(7月第一场)题解】

一、解密(看)

在这里插入图片描述
直接看
答案:YeRikGSunlRzgDlvRwYkXkrGWWhXaA

二、纪念日(SimpleDateFormat类、Date类)

在这里插入图片描述
之前几次比赛一直考Calendar类,这次终于考到了Date类,Date类注意要用SimpleDateFormat类转换成Date,yyyy-MM-dd HH:mm:ss,MM是月份(从1开始),mm是分钟,HH是24小时制,hh是12小时制。

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Main {
    public static void main(String[] args) throws ParseException {
        // HH是24小时制,MM是月份,mm是分钟,Date月份是从1月份开始,Calendar是从0开始
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = sdf.parse("1921-07-23 12:00:00");
        Date end = sdf.parse("2020-07-01 12:00:00");
        System.out.println((end.getTime() - start.getTime()) / 1000 / 60);
    }
}

赛前多看看Date、Calendar类,多半都会用上。
答案:52038720

三、合并检测(公式推导)

新冠疫情由新冠病毒引起,最近在 A 国蔓延,为了尽快控制疫情,A 国准 备给大量民众进病毒核酸检测。
然而,用于检测的试剂盒紧缺。为了解决这一困难,科学家想了一个办法:合并检测。
即将从多个人(k 个)采集的标本放到同一个试剂盒中进行检测。如果结果为阴性,则说明这 k 个人都是阴性,用一个试剂盒完成了 k 个人的检测。

如果结果为阳性,则说明至少有一个人为阳性,需要将这 k 个人的样本全部重新独立检测(从理论上看,如果检测前 k−1 个人都是阴性可以推断出第 k 个人是阳性,但是在实际操作中不会利用此推断,而是将 k 个人独立检测),
加上最开始的合并检测,一共使用 了 k + 1 个试剂盒完成了 k 个人的检测。
A 国估计被测的民众的感染率大概是 1%,呈均匀分布。

请问 k 取多少能 最节省试剂盒?
这是一道结果填空题,你只需要算出结果后提交即可。
本题的结果为一个 整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

注意,如果为阳性,那么k个人需要k+1次检测。假设有100个人,就有1个人是阳性,k=10,那么可以分成10组,每组10人,有阳性的那个组别还需要再测10次 = 10 + 10 = 20(100 / k + k)。而k=9时,分成11组还剩1个人,至于缺少的9个人可以凑,因为实际的人数是不确定的,我们只能往多的考虑,那么必须要12个组才能测完,一旦有一个组是阳性,就还要测9次(100 / k + k + 1)。

找到公式就好办了,直接遍历所有的k,找最小值。

public class Main {
    public static void main(String[] args) throws ParseException {
        int ans = Integer.MAX_VALUE;
        int sum = Integer.MAX_VALUE;
        for (int i = 1; i <= 100; i++) {
            if (100 % i == 0) {
                int tmp = 100 / i + i;
                if (tmp < sum) {
                    ans = i;
                    sum = tmp;
                }
            } else {
                int tmp = 100 / i + i + 1;
                if (tmp < sum) {
                    ans = i;
                    sum = tmp;
                }
            }
        }
        System.out.println(ans);
    }
}

答案:10

四、分配口罩(搜索)

【问题描述】
某市市长获得了若干批口罩,每一批口罩的数目如下:
(如果你把以下文 字复制到文本文件中,请务必检查复制的内容是否与文档中的一致。
在试题目 录下有一个文件 mask.txt,内容与下面的文本相同) 
9090400 
8499400 
5926800 
8547000 
4958200 
4422600 
5751200 
4175600 
6309600 
5865200 
6604400 
4635000 
10663400 
8087200 
4554000 

现在市长要把口罩分配给市内的 2 所医院。
由于物流限制,每一批口罩只能全部分配给其中一家医院。
市长希望 2 所医院获得的口罩总数之差越小越好。 
请你计算这个差最小是多少?

【答案提交】
这是一道结果填空题,你只需要算出结果后提交即可。
本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

一共15个数据,直接搜索吧。

import java.util.*;

public class Main {
    static int[] nums = new int[15];
    static int sum = 0;
    static int tmpSum = 0;
    static int ans = Integer.MAX_VALUE;
    static LinkedList<Integer> tmp = new LinkedList<>();
    public static void main(String[] args) {
        nums = new int[15];
        Scanner scan = new Scanner(System.in);
        for (int i = 0; i < 15; i++) {
            // 最后都是2个零,可以先去掉
            nums[i] = scan.nextInt();
            sum += nums[i];
        }
        dfs(0);
        System.out.println(ans);
    }
    static void dfs(int start) {
        if (tmp.size() > 1) {
            if (Math.abs(sum - tmpSum - tmpSum) < ans) {
                ans = Math.abs(sum - tmpSum - tmpSum);
                System.out.println(ans);
            }
        }
        if (tmp.size() > 9) {
            return;
        }
        for (int i = start; i < nums.length; i++) {
            tmpSum += nums[i];
            tmp.add(nums[i]);
            dfs(i + 1);
            // 回溯
            tmp.removeLast();
            tmpSum -= nums[i];
        }
    }
}

答案:2400

五、斐波那契数列最大公约数(BigInteger类)

在这里插入图片描述
把gcd和求斐波那契数列的过程换成BigInteger即可。

import java.math.BigInteger;
import java.util.*;

public class Main {
    static BigInteger gcd(BigInteger a, BigInteger b) {
        if (b.compareTo(BigInteger.valueOf(0)) == 0) return a;
        return gcd(b, a.mod(b));
    }
    public static void main(String[] args) {
        BigInteger[] f = new BigInteger[2021];
        f[1] = BigInteger.valueOf(1);
        f[2] = BigInteger.valueOf(1);
        for (int i = 3; i <= 2020; i++) {
            f[i] = f[i - 1].add(f[i - 2]);
            System.out.println(f[i]);
        }
        System.out.println(gcd(f[2020], f[520]));
    }
}

答案:6765

六、分类计数(暴力)

在这里插入图片描述
送分题…

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String str = scan.nextLine();
        int big = 0;
        int small = 0;
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9') {
                num++;
            } else if (str.charAt(i) >= 'a' && str.charAt(i) <= 'z') {
                small++;
            } else if (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') {
                big++;
            }
        }
        System.out.println(big);
        System.out.println(small);
        System.out.println(num);
    }
}

七、八次求和(BigInteger类)

【问题描述】
给定正整数 n, 求 (1^8 + 2^8 +···+ n^8) mod 123456789 。其中 mod 表示取余。
【输入格式】
输入的第一行包含一个整数 n。
【输出格式】
输出一行,包含一个整数,表示答案。
【样例输入】
2
【样例输出】
257
【样例输入】
987654
【样例输出】
43636805
【评测用例规模与约定】
对于 20% 的评测用例,1≤n≤20。
对于 60% 的评测用例,1≤n≤1000。
对于所有评测用例,1≤n≤1000000。

直接BigInteger完事啦,1000000也能通过哦。

import java.math.BigInteger;
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        BigInteger mod = BigInteger.valueOf(123456789);
        BigInteger sum = BigInteger.valueOf(0);
        for (int i = 1; i <= n; i++) {
            BigInteger tmp = BigInteger.valueOf(i);
            tmp = tmp.pow(8).mod(mod);
            sum = sum.add(tmp).mod(mod);
        }
        System.out.println(sum);
    }
}

八、字符串编码(贪心)

在这里插入图片描述

在这里插入图片描述
注意,本题只关注字典序最大,不用管长度,长度长但是字典序小是没用的。

看当前数字是否大于等于3,是的话就直接加对应的字母;小于3,就要计算后面一位和这一位共同构成的字符(当然要判断是否到了最后一个字符)。

做出上面判断的原因是,题目只要求字典序,那就必须第一个字母足够大,后续的字母也必须要大。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String str = scan.nextLine();
        // 最大字典序
        String ans = "";
        int i = 0;
        while (i < str.length()) {
            if (str.charAt(i) >= '3') {
                ans += (char)(65 + str.charAt(i) - '1');
                i++;
            } else {
                if (i + 1 == str.length()) {
                    ans += (char)(65 + str.charAt(i) - '1');
                    i++;
                } else {
                    int tmp = (str.charAt(i) - '0') * 10 + str.charAt(i + 1) - '0';
                    ans += (char)(65  + tmp - 1);
                    i += 2;
                }
            }
        }
        System.out.println(ans);
    }
}

九、BST 插入节点问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
树的问题…还不咋会

十、网络分析

在这里插入图片描述
在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@u@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值