2022年第十三届蓝桥杯省赛JAVA B组 省赛题解

目录

试题A:星期计算

试题B:山

试题C:字符统计

试题D:最少刷题数

试题E:求阶乘

试题F:最大子矩阵

试题G:数组切分

试题H:回忆迷宫

试题I:红绿灯

试题J:拉箱子 

总结:


试题A:星期计算

此题为填空题,直接利用电脑计算机计算20^22,再对此数进行取余,结果为1,所以之后是星期日即为7

答案:7

试题B:山

此题需要判别两个条件,一为回文,二为先单调不减后单调不增

package lanqiao;

public class B_山 {
	//答案:3138
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		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

 答案:3138

试题C:字符统计

利用HashMap存储每个字母出现的次数,再用TreeSet存储,使其按照字典序排列,最后输出次数最多的字母

/**
 * 
 */
package lanqiao;


import java.util.HashMap;

import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

public class C_字符统计 {


	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		String string = scanner.next();
		Map map = new HashMap<>();
		int ans_count = Integer.MIN_VALUE;
		for(int i=0;ians_count) {
				ans_count=map.get(c);
			}
		}
		Set ansCharacters = new TreeSet<>();
		for(Map.Entry entry:map.entrySet()) {
			if(entry.getValue()==ans_count) {
				ansCharacters.add(entry.getKey());
			}
		}
		for(Character c:ansCharacters) {
			System.out.print(c);
		}
		

	}

}

 试题D:最少刷题数

先对每个学生的刷题数进行从小到大排列,观察发现,需要再刷题的学生只有前半部分学生,需要刷题人数为n/2,而再刷的题目数量为中间同学的刷题量与该同学的刷题量的差值

package lanqiao;

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

public class D_最少刷题数 {

	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int N=scanner.nextInt();
		int[] arr = new int[N];
		int[] find = new int[N];
		for(int i=0;iless) {  //刷题多的多余刷题少的
				int d = more-less;
				int num = find[pos+d/2]-find[pos]+1;
				System.out.print(num+" ");
			}else {
				System.out.print(0+" ");
			}
		}
	}

}

 试题E:求阶乘

这个题考场想了很久,暴力计算肯定过不了,末尾有0就是要凑10,而只有2*5,才能得到10,所以阶乘中2的个数远远大于5,所以要凑5,注意对于25,125等数字其中包含不止一个5,所以不能直接输出5*K,当k为5时,25的阶乘末尾有6个0,所以此时应该输出-1(我就犯的这个错误,考完才发现!!!一定要多验证几个样例试一试!!!)

2022年第十三届蓝桥杯省赛JAVA B组 省赛题解_第1张图片

package lanqiao13;
 
import java.util.Scanner;
 
 
public class E {
    // 求x的阶乘后边有多少个0
    static long calc(long x){
        long res = 0;
        while (x!=0){
            res = res+x/5;
            x/=5;
        }
        return res;
    }
    //
    static void solve() {
        //第1部分代码
        //System.out.print(calc(10));//计算10的阶乘是不是后边有2个0
        //System.out.print(calc(25));//计算25的阶乘是不是后边有6个0
 
        //第2部分代码
        //System.out.print(calc(Long.MAX_VALUE/2 ));
        //Long.MAX_VALUE的阶乘后边有   2305843009213693937个0
        //Long.MAX_VALUE/2的阶乘后边有 1152921504606846964个0
 
        //二分查找
        Scanner scanner = new Scanner(System.in);
        long k = scanner.nextLong();
        long l = 1, r = Long.MAX_VALUE - 5;//l为最左边 r为最右边
        
        //long l = 1, r = 20;//方便学习可以debug
        while (l < r) {
            long mid = (l + r) / 2;
            if (k <= calc(mid)) {//如果mid的阶乘的0数大于等于k
                r = mid;//我们让r变为mid (可以等于mid)
            } else {//如果mid的阶乘的0数小于k
                l = mid + 1; //我们让l变为mid+1(大于mid,所以可以+1)
                //并且这里想让while循环中止就要不得不+1
            }
        }
        //二分法 l是最后的答案 
        if (calc(r) != k) {
            System.out.println(-1);
        } else {
            System.out.println(r);
        }
 
    }
    public static void main(String[] args) throws Exception{
        //System.out.println((Long.MAX_VALUE + 1)/2);
        // 大于Long.MAX_VALUE 会变成负数 所以有必要改进
        solve();
    }
}

 试题F:最大子矩阵

采用暴力枚举法,从大到小枚举出最大长于宽,然后枚举每一个左上角顶点,计算该矩阵是否符合要求,维护一个最大面积

package lanqiao;

import java.util.Scanner;

public class F_最大子矩阵 {
	static int[][] arr;
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		int N=scanner.nextInt();
		int M=scanner.nextInt();
		arr=new int[N][M];
		for(int i=0;i0;i--) {
			for(int j=M;j>0;j--) { // i*j的矩阵
				for(int x=0;x<=N-i;x++) {
					for(int y=0;y<=M-j;y++) {  //左上角坐标
						int max = find_max(i,j,x,y);
						int min = find_min(i,j,x,y);
						if((max-min)<=limit) {
							max_are = Math.max(max_are, i*j);
//							System.out.println(x+" "+y+" "+" "+i+" "+j);
//							System.out.println(i*j);
//							return;
						}
					}
				}
			}
		}
		System.out.println(max_are);

	}
	private static int find_min(int i, int j, int x, int y) {
		// TODO //寻找最小值
		int res = Integer.MAX_VALUE;
		for(int n=x;n

 试题G:数组切分

这个题感觉应该用深搜,无奈没做出来,附上同僚们的代码

/**
 * 
 */
package lanqiao;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class G_数组切分 {

	static boolean[] vis;

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int N = scanner.nextInt();
		int[] arr = new int[N];
		vis = new boolean[N];
		for (int i = 0; i < N; i++) {
			arr[i] = scanner.nextInt();
		}
		long ans = DFS(arr, 0);
		System.out.println(ans);

	}

	private static long DFS(int[] arr, int k) {
		if (k == arr.length-1) {
			if (check(arr)) {
//				for(int i=0;i

 试题H:回忆迷宫

暂无题解,等待大佬补充

试题I:红绿灯

在这里插入图片描述

暂无题解,等待大佬补充

试题J:拉箱子 

 暂无题解,等待大佬补充

总结:

做出来了A、B、C、D、F题,本以为E题也做出来了,结果大意了,F题也是差不多能过30%,最后是省二,希望下次能进步!

 

你可能感兴趣的:(蓝桥杯,java,蓝桥杯,开发语言)