ฅ(๑˙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
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 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分) 思路⭐ %%% 代码 最后 祝考的都会 参考链接
发表评论