2023年第十四届蓝桥杯将至,来看看第十三届蓝桥杯javaB组省赛题目如何

ฅ(๑˙o˙๑)ฅ 大家好, 欢迎大家光临我的博客:面向阿尼亚学习
算法学习笔记系列持续更新中~

阿


在这里插入图片描述


一、前言

过两天就要考蓝桥杯了,今年报的java组,今天上午做了一套第十三届蓝桥杯javaB组真题
分享一下

2道填空,8道编程


二、2022年蓝桥杯javaB组省赛真题目录

A、B为填空题

A:星期计算[5分]

在这里插入图片描述

思路⭐

本人用的快速幂取余7
然后看看比星期六多几天就可以了

代码🌟

import java.util.Scanner;

public class Main {

	static long qpow(int a, int b, int p) {
		long sum = 1;
		while (b != 0) {
			if ((b & 1) == 1) {
				sum = sum * a % p;
			}
			a = a * a % p;
			b >>= 1;
		}
		return sum;
	}

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

		System.out.println(qpow(20, 22, 7));
	}

}

答案:7

B 山(5分)

思路⭐

模拟
写两个check函数
暴力枚举符合条件的

在这里插入图片描述

代码🌟

import java.util.Scanner;

public class Main {

	static boolean check1(int x) {
		String s = Integer.toString(x);
		char c[] = s.toCharArray();
		int j = c.length - 1;
		for (int i = 0; i < j; i++, j--) {
			if (c[i] != c[j])
				return false;
		}
		return true;
	}

	static boolean check2(int x) {
		String s = Integer.toString(x);
		char c[] = s.toCharArray();
		int len = s.length();
		int mid;
		if (len % 2 == 0)
			mid = len / 2;
		else {
			mid = len / 2 + 1;
		}

		for (int i = 0; i < mid - 1; i++) {
			if (c[i] > c[i + 1])
				return false;
		}
		return true;

	}

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

		int ans = 0;
		for (int i = 2022; i <= 2022222022; i++) {
			if (check1(i)) {
				if (check2(i)) {
					ans++;

					System.out.println(i);
				}

//				System.out.println(i);
			}
		}
		System.out.println(ans);

	}

}
//3138

答案:3138


以下为编程题

C 字符统计(10分)

在这里插入图片描述

思路⭐

开个哈希表存储每个字母出现的次数
然后遍历两次
第一次求出现次数的最大值
第二次将出现次数等于最大值的字母输出即可

代码🌟

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		String s = sc.next();

		Map<Character, Integer> mp = new HashMap<>();

		char[] c = s.toCharArray();

		for (char o = 'A'; o <= 'Z'; o++) {
			mp.put(o, 0);
		}

		for (int i = 0; i < s.length(); i++) {
			int x = mp.get(c[i]);
			x++;
			mp.put(c[i], x);
		}

		int maxx = -1;
		for (char o = 'A'; o <= 'Z'; o++) {
			maxx = Math.max(maxx, mp.get(o));
		}

		for (char o = 'A'; o <= 'Z'; o++) {

			if (mp.get(o) == maxx)
				System.out.print(o);
		}
	}
}

D 最小刷题数(10分)

在这里插入图片描述

思路⭐

记录刷不同题目同学的数量
然后对其求前缀和
然后可以在O(1)的时间范围求出比某个同学刷题数多的同学
或者比他刷题少的同学
然后二分求解刷题数,结果减去原本的刷题数即可

代码🌟

import java.io.*;

public class Main {
	static int N = 200010;
	static int[] a = new int[N], cnt = new int[N];
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

	public static void main(String[] args) throws IOException {
		int n = Integer.parseInt(br.readLine());
		String[] s = br.readLine().split(" ");
		for (int i = 0; i < n; i++) {// 输入每个同学的刷题数保存到 a 数组中
			a[i] = Integer.parseInt(s[i]);
			cnt[a[i]]++;
		}
		// 前缀和
		for (int i = 1; i <= 100000; ++i) {
			cnt[i] += cnt[i - 1];
		}
		for (int i = 0; i < n; ++i) {

			// 如果比他刷题多的同学不大于比他小的同学,就不需要刷题了,直接输出0
			if (cnt[100000] - cnt[a[i]] <= cnt[Math.max(0, a[i] - 1)]) {
				out.print(0 + " ");
				continue;
			}
			// 否则进行二分
			int l = a[i], r = 100000;

			while (l + 1 < r) {// 开区间
				int mid = l + r >> 1;

				if (cnt[100000] - cnt[mid] <= cnt[mid - 1] - 1) {
					r = mid;
				} else {
					l = mid;
				}

			}

			out.print((r - a[i]) + " ");
		}
		out.flush();
	}
}

E 求阶乘(15分)

在这里插入图片描述

思路⭐

求后缀0的个数,我们可以根据阶乘的因子中2和5的个数确实,因为2*5=10,后缀多一个0
而2的个数要多于5的个数,所有只要求5的个数即可
因此后缀0的个数与n存在单调关系可以二分求
注意开long

代码🌟

import java.util.Scanner;

public class Main {

	static long k;

	// 求阶乘末尾0的个数其实就是求阶乘因子中5的个数
	static boolean check(long x) {
		long res = 0;
		//欧几里得公式
		while (x != 0) {
			res += x / 5;
			x /= 5;
		}
		return res >= k;
	}

	static long find() {
		long l = 1, r = Long.MAX_VALUE - 4;

		while (l + 1 < r) {
			long mid = (l + r) / 2;
			if (check(mid)) {
				r = mid;
			} else {
				l = mid;
			}
		}
		return r;
	}

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

// 	  System.out.println(find());

		long ans = 0;
		long p = find();

		while (p != 0) {
			ans += p / 5;
			p /= 5;
		}

		if (ans != k)
			System.out.println(-1);
		else {

			System.out.println(find());
		}

	}

}

F 最大子矩阵(15分)

在这里插入图片描述

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

思路⭐

暴力
四个循环

代码🌟

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

	public static void main(String[] args) throws IOException {
		String[] ss = in.readLine().split(" ");
		int n = Integer.parseInt(ss[0]);
		int m = Integer.parseInt(ss[1]);

		int[][] g = new int[n][m];
		for (int i = 0; i < n; i++) {
			ss = in.readLine().split(" ");
			for (int j = 0; j < m; j++)
				g[i][j] = Integer.parseInt(ss[j]);
		}
		int limit = Integer.parseInt(in.readLine());
		int res = 1;

		for (int i = 0; i < n; i++)// 枚举 行首
			for (int j = 0; j < m; j++)// 枚举 列首
				for (int x = i; x < n; x++)// 枚举 行尾
				{
					int kx = Integer.MAX_VALUE;
					int ky = Integer.MAX_VALUE;

					for (int y = j; y < m; y++)// 枚举 列尾
					{
						if (x >= kx && y >= ky)
							continue;

						if (check(g, i, j, x, y) <= limit)// 判断最大差
						{
							res = Math.max(res, (x - i + 1) * (y - j + 1));
						} else {
							kx = x;
							ky = y;
							break;
						}
					}
				}

		System.out.println(res);
	}

	private static int check(int[][] g, int xs, int ys, int xe, int ye) {
		int max = Integer.MIN_VALUE;
		int min = Integer.MAX_VALUE;

		for (int i = xs; i <= xe; i++)
			for (int j = ys; j <= ye; j++) {
				max = Math.max(max, g[i][j]);
				min = Math.min(min, g[i][j]);
			}

		return max - min;
	}

}

G 数组切分(20分)

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

在这里插入图片描述

思路⭐

如果是一段连续的自然数,满足这段区间的最大值-最小值=区间长度
然后进行动态规划

代码🌟

import java.util.Scanner;

public class Main {
	static final int N = 10007;
	static final int mod = 1000000007;
	static int[] a = new int[N];
	static int[] f = new int[N];

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();

		for (int i = 1; i <= n; i++)
			a[i] = sc.nextInt();

		f[0] = 1;
		for (int i = 1; i <= n; i++) {
			int maxx = Integer.MIN_VALUE;
			int minn = Integer.MAX_VALUE;
			for (int j = i; j >= 1; j--) {
				maxx = Math.max(maxx, a[j]);
				minn = Math.min(minn, a[j]);
				if (maxx - minn == i - j)
					f[i] = (f[i] + f[j - 1]) % mod;
			}
		}
		System.out.println(f[n]);
	}
}

H 回忆迷宫 (20分)

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

在这里插入图片描述

思路⭐

构造题
用数组表示状态

static int[][] a=new int[N][N];// 0表示没填,1表示空地,2表示墙,3表示墙外的点(外面的墙)

最后的输出

if(a[i][j] == 1 || a[i][j] == 3) System.out.printf(" "); //空地和外面的墙都要画空格
	                else System.out.printf("*"); //只要不是外面的墙,那么画墙

状态计算模拟即可

代码🌟


import java.util.Scanner;

public class Main {
	
	
	static final int N=507;
	
	static int[][] a=new int[N][N];// 0表示没填,1表示空地,2表示墙,3表示墙外的点(外面的墙)
	
	static int[] dx= {1,0,-1,0};
	static int[] dy= {0,1,0,-1};
	
	static int  maxD=-1,maxR=-1;
	static int minU=507,minL=507;

	
    static void bfs(int sx, int sy) // 将围在墙外的点标记为3
    {
        PII[] q = new PII[N * N];
        
        int hh = 0, tt = -1;
        q[++ tt] = new PII(sx, sy);

        while(hh <= tt)
        {
            PII t = q[hh ++];

            int x = t.x, y = t.y;
            for(int i = 0; i < 4; i ++) {
            	
                int xx = x + dx[i], yy = y + dy[i];
                if(xx >= 0 && xx <=500 && yy >= 0 && yy <=500 && a[xx][yy] == 0) {
                    a[xx][yy] = 3;
                    q[++ tt] = new PII(xx, yy);
                }
            }
        }
    }

	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		int n = sc.nextInt();
		
		String s = sc.next();
		
		
//		System.out.println(s);
		int x=200,y=200;
	
		a[x][y]=1;
		char c[]=s.toCharArray();
		
		
		for(int i=0;i<n;i++){
			if(c[i]=='U')
			{
				x--;
				a[x][y]=1;
			}
			else if(c[i]=='D')
			{
				x++;
				a[x][y]=1;
			}
			else if(c[i]=='L')
			{
				y--;
				a[x][y]=1;
			}
			else if(c[i]=='R'){
				y++;
				a[x][y]=1;
			}
		}
		
//		int maxD=-1,maxR=-1;
//		int minU=507,minL=507;
		
		
		for(int i=0;i<=500;i++)
		{
			for(int j=0;j<=500;j++)
			{
				if(a[i][j]==1)
				{
					
					maxD=Math.max(maxD, i);
					maxR=Math.max(maxR, j);
					minU=Math.min(minU, i);
					minL=Math.min(minL, j);
					
					for(int k=0;k<4;k++)
					{
						int xx=i+dx[k];
						int yy=j+dy[k];
						if(a[xx][yy]!=1)
						{
							a[xx][yy]=2;
						}
					}
				}
				
			}
		}
		
		
		bfs(0, 0);
		
		
//		System.out.println(minU-1);
//		System.out.println(maxD+1);
//		System.out.println(minL-1);
//		System.out.println(maxR+1);
		
		
		
		for(int i=minU-1;i<=maxD+1;i++)
		{
			for(int j=minL-1;j<=maxR+1;j++)
			{
				
				 if(a[i][j] == 1 || a[i][j] == 3) System.out.printf(" "); //空地和外面的墙都要画空格
	                else System.out.printf("*"); //只要不是外面的墙,那么画墙
				
//				System.out.print(a[i][j]);
			}
			System.out.println();
		}
		
		
		/*
17
UUUULLLLDDDDRRRRU


20
RRULUDLLULLRUURUULLU


		*/

	}
}

class PII {
    int x, y;
    PII(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

I 红绿灯(25分)

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

思路⭐

%%%

代码🌟


J 拉箱子(25分)

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

在这里插入图片描述

在这里插入图片描述

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

思路⭐

%%%

代码🌟


最后

祝考的都会

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

quicklysleep

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值