2022年第十三届蓝桥杯省赛真题及部分答案解析(Java B组)

1.星期计算

问题描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

已知今天是星期六,请问 20222022 天后是星期几?

注意用数字 11 到 77 表示星期一到星期日。

代码实现

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        int sum = 1;

        for(int i = 1;i<=2;i++){
          sum = sum*20%7;
        }
        sum = 6+sum;
        System.out.println(sum);
        scan.close();
    }
}

分析与解答

  1. 问题理解

    • 今天是星期六,即数字6。

    • 需要计算20222022天后是星期几。

    • 一周有7天,因此可以用20222022对7取余,得到的结果加上6(今天的星期数)即可。

  2. 代码逻辑

    • sum = 1:初始化变量sum为1。

    • for(int i = 1;i<=2;i++):循环两次,每次将sum乘以20后对7取余。

    • sum = 6+sum:将计算结果加上6(今天的星期数)。

    • System.out.println(sum):输出最终结果。

  3. 结果计算

    • 20222022 % 7 = 0

    • 6 + 0 = 6

    • 因此,20222022天后仍然是星期六。

2.山

问题描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

这天小明正在学数数。

他突然发现有些止整数的形状像一挫 “山”, 比㓚 123565321、145541123565321、145541, 它 们左右对称 (回文) 且数位上的数字先单调不减, 后单调不增。

小朋数了衣久也没有数完, 他惒让你告诉他在区间 [2022,2022222022][2022,2022222022] 中有 多少个数的形状像一座 “山”。

解题思路

  1. 判断回文
    首先,我们需要判断一个数字是否是回文。可以通过将数字转换为字符串,然后将其反转并与原字符串比较来实现。

  2. 判断单调性
    其次,我们需要判断数字的数位是否先单调不减,后单调不增。可以通过遍历字符串的前半部分来实现。

代码实现

以下是完整的Java代码实现:

public class day12 {
    //答案:3138
    public static void main(String[] args) {
        long ans = 0;
        for (long i = 2022; i <= 2022222022; i++) {
            if (check(i)) {
                ans++;
            }
        }
        System.out.println(ans);
    }

    private static boolean check(long i) {
        // 判断是否回文
        String string = String.valueOf(i);
        StringBuilder sBuilder = new StringBuilder(string);
        if (string.compareTo(sBuilder.reverse().toString()) == 0) {  // 是回文数
            for (int j = 0; j < string.length() / 2; j++) {
                int pre = Integer.valueOf(string.charAt(j));
                int aft = Integer.valueOf(string.charAt(j + 1));
                if (aft < pre)
                    return false;
            }
            return true;
        }
        return false;
    }
}

代码解析

  1. 主函数

    • 使用一个 for 循环遍历区间 [2022, 2022222022]

    • 对每个数字调用 check 方法,判断是否满足条件。

    • 如果满足条件,计数器 ans 增加。

  2. check 方法

    • 将数字转换为字符串 string

    • 使用 StringBuilder 对字符串进行反转,然后与原字符串比较,判断是否是回文。

    • 如果是回文,遍历字符串的前半部分,检查是否单调不减。

    • 如果所有条件都满足,返回 true,否则返回 false

运行结果

运行上述代码后,输出结果为 3138,即在区间 [2022, 2022222022] 中有 3138 个“山”形回文数字。

3.字符统计

问题描述

给定一个只包含大写字母的字符出 SS, 请你输出其中出现次数最多的字符。

如果有多个字母均出现了最多次, 按字母表顺序依次输出所有这些字母。

输入格式

一个只包含大写字母的字等串 SS.

输出格式

若干个大写字母,代表答案。

解题思路

  1. 字符数组
    将输入字符串转换为字符数组,方便逐个字符处理。

  2. 计数数组
    使用一个大小为26的整型数组 result 来记录每个字母的出现次数。数组的索引对应字母在字母表中的位置(A 对应索引0,B 对应索引1,依此类推)。

  3. 统计次数
    遍历字符数组,将每个字符的出现次数记录到 result 数组中,并同时更新最大出现次数 max

  4. 输出结果
    遍历 result 数组,找出所有出现次数等于 max 的字母,并按字母表顺序输出。

代码实现

以下是完整的Java代码实现:

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

// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        // 在此输入您的代码...
        String s = scan.nextLine();
        char[] charArray = s.toCharArray();
        int[] result = new int[26];
        int max = 0;
        Arrays.fill(result, 0);

        // 统计每个字符的出现次数
        for (int i = 0; i < charArray.length; i++) {
            result[charArray[i] - 'A']++;
            if (result[charArray[i] - 'A'] > max) {
                max = result[charArray[i] - 'A'];
            }
        }

        // 输出出现次数最多的字符
        for (int i = 0; i < 26; i++) {
            if (result[i] == max) {
                char sum = (char) ('A' + i);
                System.out.print(sum);
            }
        }
        scan.close();
    }
}

代码解析

  1. 输入处理

    • 使用 Scanner 读取用户输入的字符串 s

    • 将字符串转换为字符数组 charArray,方便逐个字符处理。

  2. 计数数组初始化

    • 使用 int[] result = new int[26] 创建一个大小为26的数组,用于记录每个字母的出现次数。

    • 使用 Arrays.fill(result, 0) 将数组初始化为0。

  3. 统计字符出现次数

    • 遍历字符数组 charArray,对于每个字符,通过 charArray[i] - 'A' 计算其在字母表中的索引,并在 result 数组中对应的索引位置加1。

    • 同时,更新最大出现次数 max

  4. 输出结果

    • 遍历 result 数组,找出所有出现次数等于 max 的字母。

    • 使用 (char) ('A' + i) 将索引转换为对应的字母,并按字母表顺序输出。          

 

4.最少刷题数

问题描述

小蓝老师教的编程课有 NN 名学生, 编号依次是 1…N1…N 。第 ii 号学生这学期 刷题的数量是 AiAi​ 。

对于每一名学生, 请你计算他至少还要再刷多少道题, 才能使得全班刷题 比他多的学生数不超过刷题比他少的学生数。

输入格式

第一行包含一个正整数 NN 。

第二行包含 NN 个整数: A1,A2,A3,…,ANA1​,A2​,A3​,…,AN​.

输出格式

输出 NN 个整数, 依次表示第 1…N1…N 号学生分别至少还要再刷多少道题。

 

解题思路

  1. 输入处理

    • 读取数组的长度 n 和数组 arr

  2. 排序辅助数组

    • 创建一个辅助数组 arr3,并将 arr 的内容复制到 arr3 中。

    • arr3 进行排序,方便后续计算。

  3. 计算最少刷题数

    • 对于每个人,计算超过他的人数 max 和低于他的人数 min

    • 如果 max <= min,则结果为0。

    • 否则,计算需要达到的刷题数,使得超过的人数大于等于总人数的一半。

  4. 输出结果

    • 将计算结果存储在数组 arr2 中,并输出。

代码实现

以下是完整的Java代码实现:

java

复制

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

// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 最少刷题数
        int n = sc.nextInt();
        int[] arr = new int[n];
        int[] arr2 = new int[n];
        int[] arr3 = new int[n];

        // 输入每个人的当前刷题数
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
            arr3[i] = arr[i];
        }

        // 对辅助数组进行排序
        Arrays.sort(arr3);

        // 计算每个人的最少刷题数
        for (int i = 0; i < n; i++) {
            int max = 0, min = 0, count = 0;
            for (int j = 0; j < n; j++) {
                if (arr[j] > arr[i]) {
                    max++;
                }
                if (arr[j] < arr[i]) {
                    min++;
                }
                if (max <= min) {
                    arr2[i] = 0;
                } else {
                    if ((max + min) % 2 == 1) {
                        count = (max + min) / 2 + 1;
                    } else {
                        count = (max + min) / 2;
                    }
                    count = count - min;
                    for (int k = 0; k < n; k++) {
                        if (arr3[k] > arr[i]) {
                            count--;
                        }
                        if (count == 0) {
                            arr2[i] = arr3[k] - arr[i] + 1;
                        }
                    }
                }
            }
        }

        // 输出结果
        for (int m : arr2) {
            System.out.print(m + " ");
        }
        sc.close();
    }
}

代码解析

  1. 输入处理

    • 使用 Scanner 读取数组的长度 n 和数组 arr

    • arr 的内容复制到辅助数组 arr3 中。

  2. 排序辅助数组

    • 使用 Arrays.sort(arr3) 对辅助数组进行排序,方便后续计算。

  3. 计算最少刷题数

    • 对于每个人,通过两层循环计算超过他的人数 max 和低于他的人数 min

    • 如果 max <= min,则结果为0。

    • 否则,计算需要达到的刷题数,使得超过的人数大于等于总人数的一半。

    • 使用辅助数组 arr3 找到需要达到的刷题数。

  4. 输出结果

    • 将计算结果存储在数组 arr2 中,并输出。

运行示例

假设输入为:

复制

5
10 20 30 40 50

程序的运行过程如下:

  1. 输入数组长度 n = 5 和数组 arr = [10, 20, 30, 40, 50]

  2. 辅助数组 arr3 = [10, 20, 30, 40, 50],排序后仍为 [10, 20, 30, 40, 50]

  3. 计算每个人的最少刷题数:

    • 对于 10,超过的人数 max = 4,低于的人数 min = 0,需要达到的刷题数为 30,最少刷题数为 30 - 10 + 1 = 21

    • 对于 20,超过的人数 max = 3,低于的人数 min = 1,需要达到的刷题数为 40,最少刷题数为 40 - 20 + 1 = 21

    • 对于 30,超过的人数 max = 2,低于的人数 min = 2,结果为 0

    • 对于 40,超过的人数 max = 1,低于的人数 min = 3,结果为 0

    • 对于 50,超过的人数 max = 0,低于的人数 min = 4,结果为 0

  4. 输出结果为:

21 21 0 0 0

 

由于蓝桥杯的试题不允许公开,因此我们无法提供完整的试题及答案解析。以下是部分题目及答案解析供参考: 1. 两个数的和 题目描述: 输入两个整数,求它们的和。 输入格式: 共一行,包含两个整数。 输出格式: 共一行,包含一个整数,表示两个整数的和。 Java代码: import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int a = in.nextInt(); int b = in.nextInt(); System.out.println(a + b); } } 2. 等差数列 题目描述: 输入一个整数n和一个整数d,输出1到n的等差数列,公差为d。 输入格式: 共一行,包含两个整数n和d。 输出格式: 共n行,每行一个整数,表示等差数列中的一个数。 Java代码: import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int d = in.nextInt(); int x = 1; for (int i = 0; i < n; i++) { System.out.println(x); x += d; } } } 3. 最长上升子序列 题目描述: 给定一个长度为n的整数序列,求它的最长上升子序列的长度。 输入格式: 共一行,包含n个整数,表示整数序列。 输出格式: 共一行,包含一个整数,表示最长上升子序列的长度。 Java代码: import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int[] a = new int[n]; int[] f = new int[n]; for (int i = 0; i < n; i++) { a[i] = in.nextInt(); f[i] = 1; } int ans = 1; for (int i = 1; i < n; i++) { for (int j = 0; j < i; j++) { if (a[j] < a[i]) { f[i] = Math.max(f[i], f[j] + 1); } } ans = Math.max(ans, f[i]); } System.out.println(ans); } } 以上是部分题目及答案解析,仅供参考。建议考生在备战蓝桥杯时,认真复习基础知识,多做题、多思考,提高解题能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值