2023年第十四届蓝桥杯JavaB组省赛真题(题目+全部完整题解)1

简介: 2023年第十四届蓝桥杯JavaB组省赛真题(题目+全部完整题解)

2023年第十四届蓝桥杯JavaB组省赛文件已上传到csdn,可自行下载

蓝桥杯题目:2023年第十四届蓝桥杯大赛软件类省赛Java大学B组真题 - 题库 - C语言网 (dotcpp.com)

详细完整题解在这篇博客:

2023年第十四届蓝桥杯省赛JavaB组个人题解(AK)_迷你滨的博客-CSDN博客

A、阶乘求和

【问题描述】

S = 1! + 2! + 3! + ... + 202320232023!,求 S 的末尾 9 位数字。

提示:答案首位不为 0

Ⅰ、题目解读

一看到三个2023的巨大数字,我想大家应该都人都麻了。但是我想说这是官方的骗术,因为题目说要求末尾的9位数,其实我想告诉大家当加到40多的阶乘时,这个阶乘和后面的9位数就不会发生改变了。

Ⅱ、代码

public class Main {
    public static void main(String[] args) {
        long start=1;
        String s="202320232023";
        long end= Long.parseLong(s);
        long sum=0;
        long cj=1;
        while (start<=end){
            cj*=start;
            cj%=1000000000;
            sum+=cj;
            sum%=1000000000;
            start++;
            if (start>40)
                System.out.println(sum);
        }
        System.out.println(sum);
    }
}

看运行

 20940313
 420940313
 420940313
 420940313
 420940313
 420940313
 420940313
 ...


这是因为40的阶乘之后后面 9位数都是0,所以阶乘之和末尾9位数不会再发生改变!


b20af502526842c2872fbf655084566c.png

B、幸运数字

【问题描述】

哈沙德数是指在某个固定的进位制当中,可以被各位数字之和整除的正整 数。例如 126 是十进制下的一个哈沙德数,因为 (126) 10 mod (1+2+6) = 0 ; 126 也是八进制下的哈沙德数,因为 (126) 10 = (176) 8 , (126) 10 mod (1 + 7 + 6) = 0 ; 同时 126 也是 16 进制下的哈沙德数,因为 (126) 10 = (7 e ) 16 , (126) 10 mod (7 + e ) = 0 。小蓝认为,如果一个整数在二进制、八进制、十进制、十六进制下均为 哈沙德数,那么这个数字就是幸运数字,第 1 至第 10 个幸运数字的十进制表示 为:1 , 2 , 4 , 6 , 8 , 40 , 48 , 72 , 120 , 126 . . . 。现在他想知道第 2023 个幸运数 字是多少?你只需要告诉小蓝这个整数的十进制表示即可。


Ⅰ、题目解读

这题就是考察大家的进制转换,数据量也不大。直接看代码吧!

Ⅱ、代码

public class {
    public static void main(String[] args) {
        int j=0;
        for (int i=1;i<10000000;i++){
            if (BaseConversion(i)){
                j++;
                if (j==2023){
                    System.out.println(i);//215040
                    break;
                }
            }
        }
    }
    public static boolean BaseConversion(int n){
        //十进制
        int sum=0;
        int x=n;
        while (x!=0){
            sum+=(x%10);
            x/=10;
        }
        if (n%sum!=0)
            return false;
        //二进制
        sum=0;
        x=n;
        while (x!=0){
            sum+=(x%2);
            x/=2;
        }
        if (n%sum!=0)
            return false;
        //八进制
        sum=0;
        x=n;
        while (x!=0){
            sum+=(x%8);
            x/=8;
        }
        if (n%sum!=0)
            return false;
        //十六进制
        int[] arr={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
        sum=0;
        x=n;
        while (x!=0){
            sum+=(arr[x%16]);
            x/=16;
        }
        if (n%sum!=0)
            return false;
        return true;
    }
}

C: 数组分割(时间限制: 1.0s 内存限制: 512.0MB)

时间限制: 1.0s

内存限制: 512.0MB

本题总分:10

【问题描述】

小蓝有一个长度为 N 的数组 A = [ A 0 , A 1 , . . . , A N − 1 ] 。现在小蓝想要从 A 对应的数组下标所构成的集合 I = { 0 , 1 , 2 , . . . , N − 1 } 中找出一个子集 R 1 ,那么 R 1在 I 中的补集为 R 2 。记 S 1 = ∑ r ∈ R 1 A r , S 2 = ∑ r ∈ R 2 A r,我们要求 S 1 和 S 2 均为 偶数,请问在这种情况下共有多少种不同的 R 1。当 R1 或 R 2 为空集时我们将 S 1 或 S 2 视为 0。

【输入格式】

第一行一个整数 T ,表示有 T 组数据。 接下来输入 T 组数据,每组数据包含两行:第一行一个整数 N ,表示数组 A 的长度;第二行输入 N 个整数从左至右依次为 A 0 , A 1 , . . . , A N − 1 ,相邻元素之 间用空格分隔。

【输出格式】

对于每组数据,输出一行,包含一个整数表示答案,答案可能会很大,你

需要将答案对 1000000007 进行取模后输出。

【样例输入】

2
2
6 6
2
1 6

【样例输出】

4

【样例说明】

对于第一组数据,答案为 4 。(注意:大括号内的数字表示元素在数组中的下标。)

R 1 = { 0 } , R 2 = { 1 } ;此时 S 1 = A 0 = 6 为偶数 , S 2 = A 1 = 6 为偶数。

R 1 = { 1 } , R 2 = { 0 } ;此时 S 1 = A 1 = 6 为偶数 , S 2 = A 0 = 6 为偶数。

R 1 = { 0 , 1 } , R 2 = {} ;此时 S 1 = A 0 + A 1 = 12 为偶数 , S 2 = 0 为偶数。

R 1 = {} , R 2 = { 0 , 1 } ;此时 S 1 = 0 为偶数 , S 2 = A 0 + A 1 = 12 为偶数。

对于第二组数据,无论怎么选择,都不满足条件,所以答案为 0 。

【评测用例规模与约定】

对于 20 % 的评测用例, 1 ≤ N ≤ 10 。

对于 40 % 的评测用例, 1 ≤ N ≤ 10 2 。

对于 100 % 的评测用例, 1 ≤ T ≤ 10 , 1 ≤ N ≤ 10 3 , 0 ≤ A i ≤ 10 9 。  

Ⅰ、解题思路

要求分割两个子集,其中一个可以为空集,且两个集合为偶数,所有第一步判断集合的总和是否为偶数,如果不为偶数则直接判定为 0 个否则再进行深度收搜判断 (暴力超时)

也可以利用奇数个数与偶数个数的排列组合实现, 将两个奇数拼接为一个偶数,判断无重复的奇数拼接情况,与偶数个数相加,递推排列组合公式  (正解)

优化排列组合,会发现是高精度算法 设 x 为偶数个数, y 为奇数个数ans = pow(x + (y == 0 ? 0 : y - 1)) % mod 算法标签:递推,找规律,贪心

注意事项:

x + (y == 0 ? 0 : y - 1), 奇数为0情况

Ⅱ、代码

//排列组合递推公式
import java.util.Scanner;
import java.math.BigInteger;
public class Main {
    public static final BigInteger MOD = new BigInteger("1000000007");
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int T = scan.nextInt();
        while (T-- > 0){
            int n = scan.nextInt();
            int[] a = new int[n];
            long x = 0, y = 0; // x 记录偶数, y 记录奇数
            for(int i = 0; i < n; i++){
                a[i] = scan.nextInt() % 2;
                if(a[i] == 0){
                    x++;
                }else {
                    y++;
                }
            }
            if(y % 2 == 1){ // 奇数个数为奇,没有一个条件成立
                System.out.println(0);
                continue;
            }
            x = x + (y == 0 ? 0 : y - 1);  // 两个奇数组合为一个偶数,排除重复情况
            BigInteger ans = new BigInteger("2");
            BigInteger dp = new BigInteger("1");
            // C(n,m) = P(n,m) / P(m,m) = n! / m! * (n - m)!
            // 转移递推公式 dp = (dp * (x, x-1, x-2, ... , n) / (1, 2, 3, ... , n))
            for(long i = 1, j = x; i < x; i++, j--){ // 排列组合无顺序 C
                BigInteger u = new BigInteger(String.valueOf(j));
                BigInteger v = new BigInteger(String.valueOf(i));
                dp = dp.multiply(u).divide(v);
                ans = ans.add(dp);
            }
            System.out.println(ans.mod(MOD));
        }
    }
}

 优化高精度

import java.util.Scanner;
import java.math.BigInteger;
public class Main {
    public static final BigInteger MOD = new BigInteger("1000000007");
    public static final BigInteger TWO = new BigInteger("2");
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int T = scan.nextInt();
        while (T-- > 0) {
            int n = scan.nextInt();
            int x = 0, y = 0; // x 记录偶数, y 记录奇数
            for (int i = 0; i < n; i++) {
                int a = scan.nextInt() % 2;
                if (a == 0) {
                    x++;
                } else {
                    y++;
                }
            }
            if (y % 2 == 1) {
                System.out.println(0);
            }else{
                System.out.println(TWO.pow(x + (y == 0 ? 0 : y - 1)).mod(MOD));
            }
        }
    }
}

D、矩形总面积(时间限制: 1.0s 内存限制: 512.0MB)

【问题描述】

平面上有个两个矩形 R 1 和 R 2 ,它们各边都与坐标轴平行。设 ( x 1 , y 1 ) 和 (x 2 , y 2 ) 依次是 R 1 的左下角和右上角坐标, ( x 3 , y 3 ) 和 ( x 4 , y 4 ) 依次是 R 2 的左下 角和右上角坐标,请你计算 R 1 和 R 2 的总面积是多少?

注意:如果 R 1 和 R 2 有重叠区域,重叠区域的面积只计算一次。

【输入格式】

输入只有一行,包含 8 个整数,依次是: x 1 , y 1 , x 2 , y 2 , x 3 , y 3 , x 4 和 y 4 。

【输出格式】

一个整数,代表答案。

【样例输入】

2 1 7 4 5 3 8 6

【样例输出】

22

【样例说明】

样例中的两个矩形如图所示:

2776caedf17f422a900bfe3082760c4f.png

【评测用例规模与约定】

对于 20 % 的数据, R 1 和 R 2 没有重叠区域。

对于 20 % 的数据,其中一个矩形完全在另一个矩形内部。

对于 50 % 的数据,所有坐标的取值范围是 [0 , 10³  ] 。

对于 100 % 的数据,所有坐标的取值范围是 [0 , 10⁵  ]

Ⅰ、题目解读

这题有两种解法,自己数组去求,但是可能数据量过大会爆栈。第二种就是公式直接求解,这时求两个矩形相交的面积改怎么求?


矩形相交要使条件成立,即min(x2,x4)-max(x1,x3)>=0 且min(y2,y4)-max(y1,y3)>=0

如果条件成立,则相交矩形面积为:(min(x2,x4)-max(x1,x3))* (min(y2,y4)-max(y1,y3))


Ⅱ、代码  

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int x1 = sc.nextInt();
        int y1 = sc.nextInt();
        int x2 = sc.nextInt();
        int y2 = sc.nextInt();
        int x3 = sc.nextInt();
        int y3 = sc.nextInt();
        int x4 = sc.nextInt();
        int y4 = sc.nextInt();
        long area1 = (long) (x2 - x1) * (y2 - y1); // 计算第一个矩形的面积
        long area2 = (long) (x4 - x3) * (y4 - y3); // 计算第二个矩形的面积
        long overlapArea=0;
        long l = Math.min(x2, x4) - Math.max(x1, x3);
        long w= Math.min(y2,y4)-Math.max(y1,y3);
        if (l >=0&&w >=0){
            overlapArea= l * w;
        }
        long Area = area1 + area2 - overlapArea; // 总面积
        System.out.println(Area); // 输出总面积
    }
}
目录
相关文章
|
2月前
|
机器学习/深度学习 算法 关系型数据库
第十五届蓝桥杯C++B组省赛
第十五届蓝桥杯C++B组省赛
115 14
|
2月前
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
57 5
|
6月前
|
人工智能 算法 搜索推荐
蓝桥杯宝藏排序题目算法(冒泡、选择、插入)
以下是内容的摘要: 本文介绍了三种排序算法:冒泡排序、选择排序和插入排序。冒泡排序通过不断交换相邻的逆序元素逐步排序,最坏情况下需要 O(n^2) 次比较。选择排序在每轮中找到剩余部分的最小元素并放到已排序序列的末尾,同样具有 O(n^2) 时间复杂度。插入排序则是将每个元素插入到已排序序列的正确位置,时间复杂度也是 O(n^2),但空间复杂度为 O(1)。
|
7月前
|
存储 人工智能 算法
第十四届蓝桥杯C++B组编程题题目以及题解
第十四届蓝桥杯C++B组编程题题目以及题解
|
7月前
|
测试技术
题目1444:蓝桥杯2014年第五届真题斐波那契
题目1444:蓝桥杯2014年第五届真题斐波那契
60 0
|
算法 Python
蓝桥杯Python组省一准备过程复盘
蓝桥杯Python组省一准备过程复盘
179 0
|
人工智能 移动开发 机器人
蓝桥杯AcWing 题目题解 - 二分与前缀和、差分
蓝桥杯AcWing 题目题解 - 二分与前缀和、差分
177 0
蓝桥杯AcWing 题目题解 - 递归与递推
蓝桥杯AcWing 题目题解 - 递归与递推
|
算法 前端开发
蓝桥杯 —— Web前端(算法类)【标题即题目链接,点击查看具体要求】
蓝桥杯 —— Web前端(算法类)【标题即题目链接,点击查看具体要求】
228 0
|
前端开发 算法
蓝桥杯 —— Web前端(页面布局类【Flex 布局】)【标题即题目链接,点击查看具体要求】
蓝桥杯 —— Web前端(页面布局类【Flex 布局】)【标题即题目链接,点击查看具体要求】
226 0