十五届蓝桥杯省赛Java B组(持续更新..)

发布于:2025-04-01 ⋅ 阅读:(25) ⋅ 点赞:(0)

十五届蓝桥杯省赛Java B组

第一题:报数

在这里插入图片描述
📚

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        long result = 202420242024L / 2 * 24;
        //思想:奇数位都是20的倍数,偶数位都是24的倍数,可知202420242024的一半为奇数,第202420242024位除以2乘以24就能得到答案
        //举个例子:第4位是第2个24的倍数,第6位是第3个24的倍数......那第202420242024位就是第101210121012个24的倍数,
        //所以答案就是:202420242024 / 2 * 24
        System.out.println(result);
        scan.close();
    }
}

主要是找规律,硬解很难解出来。

第二题:类斐波那契数

在这里插入图片描述

因为是找最大,所以逆序遍历会快点,第一个符合条件的数就是答案。

我的暴力解法,比赛不会那只能放在一边让他跑了,按道理来说是能跑出来的。

package test;

import javax.swing.*;
import java.util.*;

public class Main {

    static int N = 10000000;
    static int[] a = new int[20];
    static long[] b = new long[N];

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        for (int i = N; i >= 197; i--) {
            if(check(i)){
                System.out.println(i);
                break;
            }else {
                System.out.println(i);
            }
        }
    }

    // 检查是否是 类斐波那契 循环数
    static boolean check(int x) { // num是位数
        String str = x + "";
        int len = str.length();
        for (int i = 0; i < len; i++) {
            b[i + 1] = str.charAt(i) - '0';
        }
        for (int i = len + 1; b[i - 1] < x; i++) {
            b[i] = dfs(i);
//            System.out.println(" i:"+i);
//            System.out.println(b[i]);
            if( b[i] == x) return true;
            if( b[i] > x) return false;
        }
        return false;
    }

    // dfs递归
    static long dfs(int x){
        if(x == 1) return b[1];
        if(x == 2) return b[2];
        if(x == 3) return b[3];
        return dfs(x-1) + dfs(x - 2) + dfs(x - 3);
    }
}

📚法一

import java.util.*;

public class Main {
    static int N = 10000000;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        for (int i = N; i >= 197; i--) {
            if(check(i)){
                System.out.println(i);
                break;
            }
        }
    }

    static boolean check(int x){
        String str = x + "";
        // 获取位数
        int len = str.length();
        // 数组大小为len就够用了
        int[] dp = new int[len];
        // 将 x 每一位都拆出来
        for (int i = 0; i < len; i++) {
            dp[i] = str.charAt(i) - '0';
        }
        // 数组求和
        int sum = 0;
        for (int i = len; sum < x ; i++) {
            sum = Arrays.stream(dp).sum(); // 数组求和,注意语法
            dp[i % len] = sum; // 后面用不到的下标元素 进行替换
        }
        return sum == x;  // 两种结果:=x返回true,>x返回false
    }
}

每次求和其实只用到len个元素,所以可以对后续用不到的元素进行替换。

📚法二:


import java.util.*;

public class Main {

    static int N = 10000000;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        for (int i = N; i >= 197; i--) {
            if(check(i)){
                System.out.println(i); // 7913837
                break;
            }
        }
    }

    // 检查是否是 类斐波那契 循环数
    static boolean check(int x) { // num是位数
        String str = x + "";
        int len = str.length();
        int sum = 0;
        ArrayList<Integer> a = new ArrayList<>();
        for (int i = 0; i < len; i++) {
            int num = str.charAt(i) - '0';
            a.add(num);   // [1,9,7]
            sum += num;
        }
        //上面的这个循环究竟是在干什么事情:下面的这个以1234为例子说明,方便理解
        //列表 a 存储了整数 1234 的各个数位数字 [1, 2, 3, 4],
        // 变量 sum 的值为 10,即整数 1234 各个数位数字的总和。
        a.add(sum);
        // 此时变成了[1, 2, 3, 4,10]
        if(sum == x) return true;

        while(sum < x){
            //乘以2减去这个里面的第一个元素就是这个类斐波那契数列的规律,避免使用纯粹的数学方法计算
            sum = sum * 2 - a.get(0); 
            a.remove(0);
            a.add(sum);
            if(sum == x) return true;
        }
        return false;
    }
}

思想:要求第k+1位以后的数只需将k乘以2减去这个里面的第一个元素就是这个类斐波那契数列的规律,避免使用纯粹的数学方法计算。

第三题:分布式队列

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

👇写成这样有9个样例过不了,因为没有考虑副队列不超过主队列。

import java.util.*;

public class Main {

    static int N = 2010;
    static int INF = 100005;

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        while(sc.hasNext()){
            String str = sc.next();
            if(str.equals("add")){
                int num = sc.nextInt();
                a[0] ++;
            }else if (str.equals("sync")){
                int num = sc.nextInt();
                a[num] ++;
            } else if (str.equals("query")) {
                int ans = INF;
                for (int i = 0; i < n; i++) {
                    ans = Math.min(ans,a[i]);
                }
                System.out.println(ans);
            }
        }
    }
}

📚分布式队列

第四题 食堂

在这里插入图片描述
📚

import java.util.*;

public class Main {

    static int N = 2010;
    static int INF = 100005;

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);

        int q = sc.nextInt();
        while(q-->0) {
            int a2 = sc.nextInt();
            int a3 = sc.nextInt();
            int a4 = sc.nextInt();
            int b4 = sc.nextInt();
            int b6 = sc.nextInt();

            int sum = 0;
            // 满座 匹配4人寝坐4人桌
            while(a4 != 0 && b4 != 0){
                a4 --;b4 --;
                sum += 4;
            }
            // 满座 匹配2x2人寝坐4人桌
            while(a2 != 0 && b4 != 0){
                a2 = a2 - 2;b4 --;
                sum += 4;
            }
            // 满座 匹配2+4人寝坐6人桌
            while(a2 != 0 && a4 != 0 && b6 != 0){
                a2 --;a4 --;b6 --;
                sum += 6;
            }
            // 满座 匹配2x3人寝坐6人桌
            while(a3 != 0 && b6 != 0){
                a3 = a3 - 2;b6--;
                sum += 6;
            }
            // 满座 匹配3x2人寝坐6人桌
            while(a2 != 0 && b6 != 0){
                a2 = a2 - 3;b6 --;
                sum += 6;
            }
            // 空1座 匹配3人寝坐4人桌
            while(a3 != 0 && b4 != 0){
                a3--;b4--;
                sum += 3;
            }
            // 空1座 匹配3+2人寝坐6人桌
            while(a3 != 0 && a2 != 0 && b6 != 0){
                a3--;a2--;b6--;
                sum += 5;
            }
            // 空2座 匹配2人寝坐4人桌
            while(a2 != 0 && b4 != 0){
                a2--;b4--;
                sum += 2;
            }
            // 空2座 匹配4人寝坐6人桌
            while(a4 != 0 && b6 != 0){
                a4--;b6--;
                sum += 4;
            }
            // 空2座 匹配2x2人寝坐6人桌
            while(a2 != 0 && b6 != 0){
                a2 = a2 - 2;b6--;
                sum += 4;
            }
            // 空3座 匹配3人寝坐6人桌
            while(a3 != 0 && b6 != 0){
                a3--;b6--;
                sum += 3;
            }
            // 空4座 匹配2人寝坐6人桌
            while(a2 != 0 && b6 != 0){
                a2--;b6--;
                sum += 2;
            }
            System.out.println(sum);
        }
    }
}

🍎
在这里插入图片描述
能想出来贪心策略就不难。想不出来可以试着骗分👇

if(sum1 > sum2){
	sout(sum2)
}else if(sum1 <= sum2){
	sout(sum1)
}

5、最优分组

在这里插入图片描述

6、星际旅行

📚星际旅行

7、LITS游戏

8、拼十字

⭐️考点总结:

1.数学+1
2.暴力 构造 枚举 +1
3.模拟+1
4.贪心+1


网站公告

今日签到

点亮在社区的每一天
去签到