2023年第十四届蓝桥杯将至,来看看第十三届蓝桥杯javaB组题目如何
ฅ(๑˙o˙๑)ฅ 大家好, 欢迎大家光临我的博客:面向阿尼亚学习
算法学习笔记系列持续更新中~
文章目录
- 一、前言
- 二、2022年蓝桥杯javaB组省赛真题目录
-
- A:星期计算[5分]
-
- 思路⭐
- 代码🌟
- B 山(5分)
-
- 思路⭐
- 代码🌟
- C 字符统计(10分)
-
- 思路⭐
- 代码🌟
- D 最小刷题数(10分)
-
- 思路⭐
- 代码🌟
- E 求阶乘(15分)
-
- 思路⭐
- 代码🌟
- F 最大子矩阵(15分)
-
- 思路⭐
- 代码🌟
- G 数组切分(20分)
-
- 思路⭐
- 代码🌟
- H 回忆迷宫 (20分)
-
- 思路⭐
- 代码🌟
- I 红绿灯(25分)
-
- 思路⭐
- 代码🌟
- J 拉箱子(25分)
-
- 思路⭐
- 代码🌟
- 最后
一、前言
过两天就要考蓝桥杯了,今年报的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) {// 如果比他刷题多的同学不大于比他小的同学,就不需要刷题了,直接输出0if (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
UUUULLLLDDDDRRRRU20
RRULUDLLULLRUURUULLU*/}
}class PII {int x, y;PII(int x, int y) {this.x = x;this.y = y;}
}
I 红绿灯(25分)
思路⭐
%%%
代码🌟
J 拉箱子(25分)
思路⭐
%%%
代码🌟
最后
祝考的都会