0
点赞
收藏
分享

微信扫一扫

第十二届蓝桥杯省赛 JAVA大学 C组 题解

我阿霆哥 2022-01-26 阅读 54

第十二届蓝桥杯省赛 JAVA大学 C组 题解

A: ASC

在这里插入图片描述
代码

public class A_ASC {
    public static void main(String[] args) {
        System.out.println((int) 'L');
        // out: 76
    }
}

B: 空间

在这里插入图片描述
代码

public class B_空间 {
    public static void main(String[] args) {
        // 32位=4字节 4B,1MB = 1024KB = 1024 * 1024B
        System.out.println(256 * 1024 * 1024 / 4);
        // out: 67108864
    }
}

C: 卡片

在这里插入图片描述

思路

用一个数组记录0到9每个数字的卡片数量,每遍历一个数就减去该数字的每一位数字对应的卡片,直到某一张卡片的数量为0为止

代码

public class C_卡片 {

    private static boolean sub(int num, int[] A){
        while (num > 0){
            int mod = num % 10;
            if (A[mod] == 0) return false;
            else A[mod]--;
            num /= 10;
        }
        return true;
    }

    public static void main(String[] args) {
        int[] cnt = new int[10];
        Arrays.fill(cnt, 2021);
        int num = 1;
        while (sub(num, cnt)) num++;
        System.out.println(num - 1);
        // out: 3182
    }
}

D: 相乘

在这里插入图片描述

思路

直接暴力

代码

public class D_相乘 {
    public static void main(String[] args) {
        long mod = 1000000007;
        long res = 0;
        for (long i = 40000; i < mod; i++) {
            if (i * 2021 % mod == 999999999) {
                res = i;
                break;
            }
        }
        System.out.println(res);
        // out: 17812964
    }
}

E: 路径

在这里插入图片描述

思路

贪心,应为两条路径最多相差21,当数很大之后最小公倍数也会很大,所以保持所走的每个点都是某个值的倍数以保证最小公倍数保持最小,经过不严格的归纳总结出每次走21的倍数可以保证最小公倍数最小,当然21不是2021的因数,最后还有某个数要乘以2021再加上前面的公倍数之和就是最短路径。(没有严格证明,我也不敢保证是否正确😂

代码

public static void main(String[] args) {
        int i = 1;
        int n = 21;
        int total = 0;
        while (n <= 2021){
            System.out.println(n);
            total += i++ * n;
            n += 21;
        }
        System.out.println(total +  (n - 21) * 2021);
        // out: 10364592 蒙的
    }

F: 时间显示

在这里插入图片描述

思路

没啥好说的,直接调API,不过注意题目是从0点开始,javaAPI是从8点开始,用给的时间戳减去八个小时即可

代码

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class F_时间显示 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        DateFormat df = new SimpleDateFormat("HH:mm:ss");
        Date date = new Date(scan.nextLong() - 1000 * 60 * 60 * 8);
        String sTime = df.format(date);
        System.out.println(sTime);
    }
}

G: 最少砝码

在这里插入图片描述

思路

不要给样例给骗了,这题的本质是二进制,因为每个数都可以用二进制表示,二进制的每一位就可以表示该位上的数字,比如数字7的二进制是111,用其权重代表重量位4,2,1的砝码,这三个二进制位就可以表示7以下的数,比如8的二进制是1000,表示有需要4个砝码,重量分别位8,4,2,1。所以结果就是把整数转换位二进制之后的长度。

代码

import java.util.Scanner;

public class G_最少砝码 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        String s = Integer.toBinaryString(N);
        System.out.println(s.length());
    }
}

H: 杨辉三角

在这里插入图片描述

思路

滚动数组,使用一维列表保存每一层的结果,一层一层的遍历

代码

import java.util.*;

public class H_杨辉三角 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        List<Integer> lst = new ArrayList<>();
        lst.add(1);
        int res = 0;
        int row = 2;
        boolean flag = true;
        while (flag){
            for (Integer i : lst) {
                res++;
                if (i == N) {
                    System.out.println(res);
                    flag = false;
                    break;
                }
            }
            List<Integer> t = new ArrayList<>();
            for (int i = 0; i < row; i++) {
                if (i == 0 || i == row - 1) t.add(1);
                else   t.add(lst.get(i - 1) + lst.get(i));
            }
            row++;
            lst = t;
        }
    }
}

I: 左孩子右兄弟

在这里插入图片描述

思路

贪心+记忆化搜索,先将每个节点的子节点存入哈希表,递归求高度最高的子节点,整棵树的最大高度就是子节点的数量加上最长子节点的高度,找最长的子节点,拼到最后。将已访问过的节点加入缓存避免重复计算。

代码

import java.util.*;

public class I_左孩子右兄弟 {
    static Map<Integer, List<Integer>> map = new HashMap<>();
    static Map<Integer, Integer> cache = new HashMap<>();
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        for (int i = 2; i <= N; i++) {
            int p = scan.nextInt();
            map.putIfAbsent(p, new ArrayList<>());
            map.get(p).add(i);
        }
        System.out.println(getMaxHigh(1) - 1);
        System.out.println(map);
    }

    static int getMaxHigh(int c){
        if (!map.containsKey(c)) cache.put(c, 1);
        if (cache.containsKey(c)) return cache.get(c);
        List<Integer> children = map.get(c);
        int size = children.size();
        int maxChildren = 0;
        for (Integer child : children) {
            maxChildren = Math.max(maxChildren, getMaxHigh(child));
        }
        cache.put(c, size + maxChildren);
        return cache.get(c);
    }
}

J: 双向排序

在这里插入图片描述

思路

直接调API(妥妥的超时,目前还没想出其他写法

代码

import java.util.Arrays;
import java.util.Scanner;

public class J_双向排序 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt(), m = scan.nextInt();
        Integer[] arr = new Integer[n];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i + 1;
        }
        while (m-- != 0) {
            int p = scan.nextInt(), idx = scan.nextInt();
            if (p == 0) Arrays.sort(arr,  0, idx, (a, b) -> b - a);
            else Arrays.sort(arr, idx - 1, n);
        }
        for (Integer i : arr) {
            System.out.print(i + " ");
        }
    }
}

总结

还是有点难度,还请各位大佬指点指点

举报

相关推荐

0 条评论