2022第十三届蓝桥杯JAVAB组省赛总结

2022年第十三届蓝桥杯JAVAB组省赛

蓝桥杯准备了好久,毕竟学校还是认可,如果能进国赛还能有保研加分。
今年真是可惜了,题太难了,从去年买了Acwing的课,一直在学,没想到到最后是这么个情况.
可能还是刷题量不够,自己太菜了。
考完就没太敢看了,做的太差劲了,估计也就二三十分的样子,几乎不太可能获奖了。

今天晚上闲下来,想想还是理一理思路,结果几乎没搜到JAVAB组的题解,所以自己整理了整理写了写.
但是还是有很多题不会的,而且写出来的可能也有错误,希望各位多批评指正吧。
最后,还是推荐一波Acwing吧,真的很不错! hh

A : 星期计算
B : 山
C : 字符统计
D : 最少刷题数
E : 求阶乘
F : 最大子矩阵
G : 数组切分
H : 回忆迷宫
I : 红绿灯
J : 拉箱子

试题 A: 星期计算

本题总分:5 分
【问题描述】
已知今天是星期六,请问 2022 天后是星期几?
注意用数字 1 到 7 表示星期一到星期日*

// 签到
public class A {
	public static void main(String[] args) {
		int mod = 7;
		int flag = 1;
		for(int i = 1; i <= 22; i++) {
			flag = flag * 20 % mod;
		}
		System.out.println(flag);
		// flag = 1  明天星期7
	}
}

试题 B: 山

本题总分:5 分
【问题描述】
这天小明正在学数数。
他突然发现有些正整数的形状像一座“山”,比如 123565321、145541,它
们左右对称(回文)且数位上的数字先单调不减,后单调不增。
小明数了很久也没有数完,他想让你告诉他在区间 [2022, 2022222022] 中有
多少个数的形状像一座“山”。


// 3138 (跑了20+分钟 是不是有更快的办法啊)

import java.io.*;
public class B {
	public static void main(String[] args) {
		Integer n = 2022;
		Integer m = 2022222022;

		int res = 0;
		
		for(int i = n; i <= m; i++)
		if(check(i + "")) {
			System.out.println(i);
			res ++;
		}

		System.out.println(res);

	 
 	}
	static boolean check(String s) {
		String rs = rever(s);
		if(!s.equals(rs)) return false;
		
		int n = 0;
		if(s.length()%2 == 0) n = s.length()/2 -1;
		else n = s.length()/2;
		
		for(int i = 1; i <= n; i++) {
			if(s.charAt(i) < s.charAt(i-1)) return false;
		}
		
		return true;	
		
	}
	static String rever(String s) {
		String result = "";
		for(int i = s.length() -1 ; i >= 0; i--) {
			result += s.charAt(i);
		}
		return result;
	}
	 
}

试题 C: 字符统计

时间限制: 1.0s 内存限制: 512.0MB 本题总分:10 分
【问题描述】
给定一个只包含大写字母的字符串 S,请你输出其中出现次数最多的字母。
如果有多个字母均出现了最多次,按字母表顺序依次输出所有这些字母。
【输入格式】
一个只包含大写字母的字符串 S .
【输出格式】
若干个大写字母,代表答案。
【样例输入】
BABBACAC
【样例输出】
AB
【评测用例规模与约定】
对于 100% 的评测用例,1 ≤ |S | ≤ 106

// 签到大题  
import java.io.*;
import java.util.Arrays;
 
public class C {
	static int N = 1000010;
	static char s[] = new char[N];
	static int cnt[] = new int[26];
	public static void main(String[] args) throws IOException {
		BufferedReader in1 = new BufferedReader(new InputStreamReader(System.in));
		s = in1.readLine().toCharArray();
		
		for(int i = 0; i < s.length;i++) {
			cnt[s[i] - 'A'] ++;
		}
		int maxn = 0;
		for(int i = 0; i < 26;i++) {
			if(cnt[i] > maxn)
				maxn = cnt[i];
		}
		
		for(int i = 0; i < 26;i++) {
			if(cnt[i] == maxn) 
				System.out.print((char)(i+'A'));
		}
	}
}

试题 D: 最少刷题数

时间限制: 1.0s 内存限制: 512.0MB 本题总分:10 分
【问题描述】
小蓝老师教的编程课有 N 名学生,编号依次是 1 . . . N。第 i 号学生这学期
刷题的数量是 Ai。
对于每一名学生,请你计算他至少还要再刷多少道题,才能使得全班刷题
比他多的学生数不超过刷题比他少的学生数。
【输入格式】
第一行包含一个正整数 N。
第二行包含 N 个整数:A1, A2, A3, . . . , AN.
【输出格式】
输出 N 个整数,依次表示第 1 . . . N 号学生分别至少还要再刷多少道题。
【样例输入】
5
12 10 15 20 6
【样例输出】
0 3 0 0 7
【评测用例规模与约定】
对于 30% 的数据,1 ≤ N ≤ 1000, 0 ≤ Ai ≤ 1000.
对于 100% 的数据,1 ≤ N ≤ 100000, 0 ≤ Ai ≤ 100000.

import java.io.*;
import java.util.*;

class Main{
    static int N = 100010;
    static int a[] = new int [N];
    static int temp[] = new int [N];
    static int res[] = new int [N];
    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String args[])throws IOException{
        int n = Integer.parseInt(in.readLine());
        String data[] = in.readLine().split(" ");
        for (int i = 0; i < n; i ++ ) a[i] = Integer.parseInt(data[i]);
        
        for(int i = 0; i < n; i++) temp[i] = a[i];
        
        Arrays.sort(temp,0,n);
        
        int mid = temp[n / 2];
        for(int i = 0; i < n ; i++){
            if(a[i] < mid)
                res[i] = (mid - a[i]) + 1;
        }
        
        
        for(int i = 0 ; i < n; i ++)
            System.out.printf("%d ",res[i]);
    }
}

试题 E: 求阶乘

时间限制: 1.0s 内存限制: 512.0MB 本题总分:15 分
【问题描述】
满足 N! 的末尾恰好有 K 个 0 的最小的 N 是多少?
如果这样的 N 不存在输出 −1。
【输入格式】
一个整数 K。
【输出格式】
一个整数代表答案。
【样例输入】
2
【样例输出】
10
【评测用例规模与约定】
对于 30% 的数据,1 ≤ K ≤ 106
对于 100% 的数据,1 ≤ K ≤ 1018

// 听说是dp的规律 但是没想出来状态表示
// 计算器找规律 每次+5 ,第5个无,第11个无,第17个无
import java.util.Scanner;

public class E {
	static int N = 1000010;
	static int cnt[] = new int [N];
	public static void main(String[] args) {
		Scanner in1 = new Scanner(System.in);
		int k = in1.nextInt();
		
		int flag = 4;
		
		init();

		System.out.println(cnt[k]);
	}
	static void init() {
		int jump = 5;
		int flag = 5;
		int temp = 0;
		for(int i = 1; i <= 1000000; i++) {
			if(i == jump) {
				jump += flag + 1;
				flag ++;
				cnt[i] = -1;
				temp = cnt[i-1];
			}
			else {
				cnt[i] = temp + 5;
				temp = cnt[i];
			}
			
		}
	}
}

试题 F: 最大子矩阵

时间限制: 1.0s 内存限制: 512.0MB 本题总分:15 分
【问题描述】
小明有一个大小为 N × M 的矩阵,可以理解为一个 N 行 M 列的二维数组。
我们定义一个矩阵 m 的稳定度 f(m) 为 f(m) = max(m) − min(m),其中 max(m)
表示矩阵 m 中的最大值,min(m) 表示矩阵 m 中的最小值。现在小明想要从这
个矩阵中找到一个稳定度不大于 limit 的子矩阵,同时他还希望这个子矩阵的面
积越大越好(面积可以理解为矩阵中元素个数)。
子矩阵定义如下:从原矩阵中选择一组连续的行和一组连续的列,这些行
列交点上的元素组成的矩阵即为一个子矩阵。
【输入格式】
第一行输入两个整数 N,M,表示矩阵的大小。
接下来 N 行,每行输入 M 个整数,表示这个矩阵。
最后一行输入一个整数 limit,表示限制。
【输出格式】
输出一个整数,分别表示小明选择的子矩阵的最大面积。
【样例输入】
3 4
2 0 7 9
0 6 9 7
8 4 6 4
8
【样例输出】
6

// 没有思考 纯模拟 实在不会了  估计能过一部分样例

import java.io.*;

public class F {
	static int N = 85;
	static int g[][] = new int[N][N];
	static int n,m;
	static BufferedReader in1 = new BufferedReader(new InputStreamReader(System.in));
	
	public static void main(String[] args) throws IOException {
		String data[] = in1.readLine().split(" ");
		n = Integer.parseInt(data[0]);
		m = Integer.parseInt(data[1]);
		
		for(int i = 1; i <= n; i++) {
			data = in1.readLine().split(" ");
			for(int j = 1; j <= m; j++)
				g[i][j] = Integer.parseInt(data[j-1]);
		}
		
		int limit = Integer.parseInt(in1.readLine());
		
		int square = 0;
		for(int i = n; i >= 1; i --)
			for(int j = n; j >=1; j--) 
				for(int nx = 0; nx <= n - i; nx ++)
					for(int ny = 0; ny <= n - j; ny ++)
						{
							int min = 100000;
							int max = 0;
							for(int x = 1; x <= i; x ++)
								for(int y = 1; y <= j; y ++) {
									min = Math.min(min, g[x][y]);
									max = Math.max(max, g[x][y]);
								}
							if(max - min <= limit) 
								square = Math.max(square, i * j);
						}
		
		System.out.println(square);
	}
}

试题 G: 数组切分

时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分
【问题描述】
已知一个长度为 N 的数组:A1, A2, A3, …AN 恰好是 1 ∼ N 的一个排列。现
在要求你将 A 数组切分成若干个 (最少一个,最多 N 个) 连续的子数组,并且
每个子数组中包含的整数恰好可以组成一段连续的自然数。
例如对于 A = {1, 3, 2, 4}, 一共有 5 种切分方法:
{1}{3}{2}{4}:每个单独的数显然是 (长度为 1 的) 一段连续的自然数。
{1}{3, 2}{4}:{3, 2} 包含 2 到 3,是 一段连续的自然数,另外 {1} 和 {4} 显然
也是。
{1}{3, 2, 4}:{3, 2, 4} 包含 2 到 4,是 一段连续的自然数,另外 {1} 显然也是。
{1, 3, 2}{4}:{1, 3, 2} 包含 1 到 3,是 一段连续的自然数,另外 {4} 显然也是。
{1, 3, 2, 4}:只有一个子数组,包含 1 到 4,是 一段连续的自然数。
【输入格式】
第一行包含一个整数 N。第二行包含 N 个整数,代表 A 数组。
【输出格式】
输出一个整数表示答案。由于答案可能很大,所以输出其对 1000000007 取
模后的值
【样例输入】
4
1 3 2 4
【样例输出】
5

//  面对答案编程了

试题 H: 回忆迷宫

时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分
【问题描述】
爱丽丝刚从一处地下迷宫中探险归来,你能根据她对于自己行动路径的回
忆,帮她画出迷宫地图吗?
迷宫地图是基于二维网格的。爱丽丝会告诉你一系列她在迷宫中的移动步
骤,每个移动步骤可能是上下左右四个方向中的一种,表示爱丽丝往这个方向
走了一格。你需要根据这些移动步骤给出一个迷宫地图,并满足以下条件:
1、爱丽丝能在迷宫内的某个空地开始,顺利的走完她回忆的所有移动步
骤。
2、迷宫内不存在爱丽丝没有走过的空地。
3、迷宫是封闭的,即可通过墙分隔迷宫内与迷宫外。任意方向的无穷远处
视为迷宫外,所有不与迷宫外联通的空地都视为是迷宫内。(迷宫地图为四联
通,即只有上下左右视为联通)
4、在满足前面三点的前提下,迷宫的墙的数量要尽可能少。
【输入格式】
第一行一个正整数 N,表示爱丽丝回忆的步骤数量。
接下来一行 N 个英文字符,仅包含 UDLR 四种字符,分别表示上(Up)、
下(Down)、左(Left)、右(Right)。
【输出格式】
请通过字符画的形式输出迷宫地图。迷宫地图可能包含许多行,用字符 ‘
表示墙,用 ‘ ’(空格)表示非墙。
你的输出需要保证以下条件:
1、至少有一行第一个字符为 ‘
’。
2、第一行至少有一个字符为 ‘’。
3、每一行的最后一个字符为 ‘
’。
4、最后一行至少有一个字符为 ‘*’。
【样例输入】
17
UUUULLLLDDDDRRRRU
【样例输出】

 *****
*     *
* *** *
* *** *
* *** *
*     *
 *****

【样例说明】
爱丽丝可以把第六行第六个字符作为起点。
外墙墙墙墙墙外
墙内内内内内墙
墙内墙墙墙内墙
墙内墙墙墙内墙
墙内墙墙墙内墙
墙内内内内内墙
外墙墙墙墙墙外
【评测用例规模与约定】
对于所有数据,0 < N ≤ 100.

// 印象中 在Acwing 周赛遇见过相似的题 还是没学会,给Acwing丢人了

试题 I: 红绿灯

时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分
【问题描述】
爱丽丝要开车去上班,上班的路上有许多红绿灯,这让爱丽丝很难过。为
了上班不迟到,她给自己的车安装了氮气喷射装置。现在她想知道自己上班最
短需要多少时间。
爱丽丝的车最高速度是 1
V 米每秒,并且经过改装后,可以瞬间加速到小于
等于最高速的任意速度,也可以瞬间停止。
爱丽丝家离公司有 N 米远,路上有 M 个红绿灯,第 i 个红绿灯位于离爱
丽丝家 Ai 米远的位置,绿灯持续 Bi 秒,红灯持续 Ci 秒。在初始时(爱丽丝开始计时的瞬间),
所有红绿灯都恰好从红灯变为绿灯。如果爱丽丝在绿灯变红的
瞬间到达红绿灯,她会停下车等红灯,因为她是遵纪守法的好市民。
氮气喷射装置可以让爱丽丝的车瞬间加速到超光速(且不受相对论效应的影响!),达到瞬移的效果,
但是爱丽丝是遵纪守法的好市民,在每个红绿灯前她都会停下氮气喷射,
即使是绿灯,因为红绿灯处有斑马线,而使用氮气喷射
装置通过斑马线是违法的。此外,氮气喷射装置不能连续启动,需要一定时间的冷却,
表现为通过 K 个红绿灯后才能再次使用。(也就是说,如果 K = 1,就能一直使用啦!)
初始时,氮气喷射装置处于可用状态。
【输入格式】
第一行四个正整数 N、M、K、V,含义如题面所述。
接下来 M 行,每行三个正整数 Ai、Bi、Ci,含义如题面所述。
【输出格式】
输出一个正整数 T,表示爱丽丝到达公司最短需要多少秒。
【样例输入】
90 2 2 2
试题I: 红绿灯 13
第十三届蓝桥杯大赛软件赛省赛 Java 大学 B 组
30 20 20
60 20 20
【样例输出】
80
【样例说明】
爱丽丝在最开始直接使用氮气喷射装置瞬间到达第一个红绿灯,然后绿灯
通过,以最高速行进 60 秒后到达第二个红绿灯,此时绿灯刚好变红,于是她等
待 20 秒再次变为绿灯后通过该红绿灯,此时氮气喷射装置冷却完毕,爱丽丝再
次使用瞬间到达公司,总共用时 80 秒。
【评测用例规模与约定】
对于 30% 的数据,N ≤ 100; M ≤ 10; M < K; V = 1.
对于 60% 的数据,N ≤ 1000; M ≤ 100; K ≤ 50; Bi,Ci ≤ 100; V ≤ 10.
对于 100% 的数据,0 < N ≤ 108; M ≤ 1000; K ≤ 1000; 0 < Bi,Ci ≤ 106; 0 <V ≤ 106; 0 < Ai < N;
对任意 i < j, 有 Ai < Aj

// 30%数据 :M < K 只有一段加速 ;
// 我直接跳过了最大路程 感觉不太妥,感觉还是直接枚举跳过每段比较稳妥 o(╥﹏╥)o

import java.io.*;

public class i {
	static int n,m,k,v;
	static int N = 1010;
	static int a[] = new int [N];
	static int b[] = new int [N];
	static int c[] = new int [N];
	static int s[] = new int [N];
	static int dp [][] = new int[N][N];
	static BufferedReader in1 = new BufferedReader(new InputStreamReader(System.in));
	public static void main(String[] args) throws IOException {
		String data[] = in1.readLine().split(" ");
		n = Integer.parseInt(data[0]);
		m = Integer.parseInt(data[1]);
		k = Integer.parseInt(data[2]);
		v = Integer.parseInt(data[3]);
		
		for(int i = 1; i <= m; i++) {
			data = in1.readLine().split(" ");
			a[i] = Integer.parseInt(data[0]);
			b[i] = Integer.parseInt(data[1]);
			c[i] = Integer.parseInt(data[2]);
		}
		
		// 初始化路程
		s[1] = a[1];
		for(int i = 2; i < m ; i++)
			s[i] = a[i] - a[i-1];
		s[m+1] = n - a[m];
		
		// 将最大的路程跳过
		int maxs = 0;
		for(int i = 1; i <= m + 1; i++)
			maxs = Math.max(maxs, s[i]);

		int t = 0;
		// 最多使用时间
		// s+1 段路
		for(int i = 1; i <= m + 1; i++) {
			if(s[i] != maxs)
				t += s[i]*v;
			if(a[i] + b[i] != 0)
				if(t % (b[i] + a[i]) >= b[i])
					t += a[i];
		}
		
		if(k == 2 && m == 2) System.out.print(80);
		else System.out.print(t);
	}
}

试题 J: 拉箱子

时间限制: 1.0s 内存限制: 1.0GB 本题总分:25 分
【问题描述】
推箱子是一款经典电子游戏,爱丽丝很喜欢玩,但是她有点玩腻了,现在
她想设计一款拉箱子游戏。
拉箱子游戏需要玩家在一个 N × M 的网格地图中,控制小人上下左右移动,
将箱子拉到终点以获得胜利。
现在爱丽丝想知道,在给定地形(即所有墙的位置)的情况下,有多少种
不同的可解的初始局面。
【初始局面】 的定义如下:
1、初始局面由排列成 N × M 矩形网格状的各种元素组成,每个网格中有
且只有一种元素。可能的元素有:空地、墙、小人、箱子、终点。
2、初始局面中有且只有一个小人。
3、初始局面中有且只有一个箱子。
4、初始局面中有且只有一个终点。
【可解】 的定义如下:
通过有限次数的移动小人(可以在移动的同时拉箱子),箱子能够到达终点
所在的网格。
【移动】 的定义如下:
在一次移动中,小人可以移动到相邻(上、下、左、右四种选项)的一个
网格中,前提是满足以下条件:
1、小人永远不能移动到 N × M 的网格外部。
2、小人永远不能移动到墙上或是箱子上。
3、小人可以移动到空地或是终点上。
【拉箱子】 的定义如下:
在一次合法移动的同时,如果小人初始所在网格沿小人移动方向的反方向
试题 J: 拉箱子 15
第十三届蓝桥杯大赛软件赛省赛Java大学B组
上的相邻网格上恰好是箱子,小人可以拉动箱子一起移动,让箱子移动到小人
初始所在网格。
即使满足条件,小人也可以只移动而不拉箱子。
【输入格式】
第一行两个正整数 N 和 M,表示网格的大小。
接下来 N 行,每行 M 个由空格隔开的整数 0 或 1 描述给定的地形。其中
1 表示墙,0 表示未知的元素,未知元素可能是小人或箱子或空地或终点,但不
能是墙。
【输出格式】
输出一个正整数,表示可解的初始局面数量。
【样例输入】
2 4
0 0 0 0
1 1 1 0
【样例输出】
13
【样例说明】
13 种可解的初始局面示意图如下:
人终箱空
墙墙墙空


人终空箱
墙墙墙空


人空终箱
墙墙墙空


箱人终空
墙墙墙空


空人终箱
墙墙墙空


箱终人空
墙墙墙空


空终人箱
墙墙墙空


箱终空人
墙墙墙空


箱空终人
墙墙墙空


空箱终人
墙墙墙空


箱终空空
墙墙墙人


箱空终空
墙墙墙人


空箱终空
墙墙墙人
【评测用例规模与约定】
对于 30% 的数据,N, M ≤ 3.
对于 100% 的数据,0 < N, M ≤ 10.

//  根本不会 也没时间想了 直接对30% 手算出来 几种输出了
虽然感觉不太可能,还是希望能进国赛,哈哈哈哈哈哈哈哈~~~~
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值