2022第13届蓝桥杯Java省赛B组个人题解

A. 星期计算

在这里插入图片描述
思路解析:

大整数类的应用,计算幂后对其取余。官方给的计算器也能直接计算其值

答案:

取余结果为1,所以答案为7

代码:

package lanqiao;

import java.math.BigInteger;
//答案:6+1=7
public class A_星期计算 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BigInteger num = new BigInteger("20");
		BigInteger ans = new BigInteger("1");
		for(int i=1;i<=22;i++) {
			ans = ans.multiply(num);
		}
		System.out.println(ans);
		System.out.println(ans.mod(new BigInteger("7")));
	}
}

B. 山

在这里插入图片描述
思路解析:

因为只是个填空题,可以暴力枚举,判断是否为回文数(字符串翻转和原串相同)以及前n/2是否满足递增

答案:

3138

代码:

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<string.length()/2;j++) {
				int pre = Integer.valueOf(string.charAt(j));
				int aft = Integer.valueOf(string.charAt(j+1));
				if(aft<pre)
					return false;
			}
			System.out.println(i);
			return true;
		}
		return false;
	}

}

C. 字符统计

在这里插入图片描述
思路解析:

在输入的时候,记录出现字符最多的次数,并将每个字符以及其次数用HashMap存储。再次遍历HashMap,将出现次数等于最多的加入到一个TreeSet中,最后TreeSet能维持字典序,输出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<Character, Integer> map = new HashMap<>();
		int ans_count = Integer.MIN_VALUE;
		for(int i=0;i<string.length();i++) {
			char c = string.charAt(i);
			if(map.get(c)==null) {
				map.put(c, 1);
			}else {
				map.put(c, map.get(c)+1);
			}
			if(map.get(c)>ans_count) {
				ans_count=map.get(c);
			}
		}
		Set<Character> ansCharacters = new TreeSet<>();
		for(Map.Entry<Character, Integer> entry:map.entrySet()) {
			if(entry.getValue()==ans_count) {
				ansCharacters.add(entry.getKey());
			}
		}
		for(Character c:ansCharacters) {
			System.out.print(c);
		}
		

	}

}

D. 最少刷题数

在这里插入图片描述
思路解析:

采用arr与find两个数组存储N个整数,将find进行sort排序,遍历arr,在find中二分查找arr[i]的位置pos,然后可以计算出小于arr[i]与大于arr[i]的数目之差d,如果不满足小于其的数量多余大于其的数量,则输出find[pos+d/2]-find[pos]+1

代码:

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;i<N;i++) {
			int num = scanner.nextInt();
			arr[i]=num;
			find[i]=num;
		}
		Arrays.sort(find);
		for(int i=0;i<N;i++) {
			//在find中查找arr[i]的位置
			int pos = Arrays.binarySearch(find, arr[i]);
			//计算其左边的数
			int less = pos;
			int more = N-pos-1;
			if(more>less) {  //刷题多的多余刷题少的
				int d = more-less;
				int num = find[pos+d/2]-find[pos]+1;
				System.out.print(num+" ");
			}else {
				System.out.print(0+" ");
			}
		}
	}

}

E. 求阶乘

在这里插入图片描述
思路解析:

个人感觉这道题比较难,想了很久,只知道要想凑个10,就必须要有一个2和5,但是明显在一个阶乘里,因子为2的数量一定多余5的数量,所以计算5的数量,但是感觉代码写出来后,测试一些样例还是不对(欢迎讨论探讨)

代码:

package lanqiao;

import java.util.Scanner;

public class E_求阶乘 {
	static int[] rec;
	//一个2与一个5可以产生一个0;在N的阶乘中,2的数目肯定多余5的数目,所以考虑5的数目就可以
	public static void main(String[] args) {
		rec=new int[100000000];
		Scanner scanner=new Scanner(System.in);
		long k=scanner.nextLong();
		int num=5;
		rec[5]=1;
		while(k>0) {
			int count = f(num);  //计算num中含有多少个5
			k-=count;
			if(k<=0)break;
			num+=5;
		}
		if(k<0) {
			System.out.println(-1);
		}else {
			System.out.println(num);
		}
	}

	private static int f(int num) {
		if(rec[num]!=0||num<5) {
			return rec[num];
		}
		if(num%5==0) {
			int res = 1+f(num/5);
			rec[num]=res;
			return res;
		}else {
			rec[num]=0;
			return 0;
		}
		
		
	}

}

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;i<N;i++) {
			for(int j=0;j<M;j++) {
				arr[i][j]=scanner.nextInt();
			}
		}
		int limit = scanner.nextInt();
		int max_are = Integer.MIN_VALUE;
		for(int i=N;i>0;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<x+i;n++) {
			for(int m=y;m<y+j;m++) {
				res = Math.min(res, arr[n][m]);
			}
		}
		return res;
	}
	private static int find_max(int i, int j, int x, int y) {
		// TODO 寻找最大值
		int res = Integer.MIN_VALUE;
		for(int n=x;n<x+i;n++) {
			for(int m=y;m<y+j;m++) {
				res = Math.max(res, arr[n][m]);
			}
		}
		return res;
	}

}

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<vis.length;i++) {
//					System.out.print(vis[i] + " ");
//				}
//				System.out.println();
				return 1;
			}
			return 0;
		}
		// 当前位置切
		int res = 0;
		vis[k] = true;
		res += DFS(arr, k + 1);
		// 当前位置不切
		vis[k] = false;
		res += DFS(arr, k + 1);
		return res;
	}

	private static boolean check(int[] arr) {
		// TODO 检查当前切法是否符合规则
		int len = arr.length;
		int p = 0;
		int q = 1;
		while (q < len) {
			if (vis[q - 1]) {
				if (!check_lianxu(arr, p, q)) {
					return false;
				}
				p=q;
			}
			q++;
		}
		if(!check_lianxu(arr, p, q)) {
			return false;
		}
		return true;
	}

	private static boolean check_lianxu(int[] arr, int p, int q) {
		// TODO 检测数组是否连续p-q

		int[] arrcopy = new int[q-p];
		System.arraycopy(arr, p, arrcopy, 0, q-p);
		Arrays.sort(arrcopy);
		for(int i=0;i<q-p-1;i++) {
			if(arrcopy[i+1]-arrcopy[i]!=1) {
				return false;
			}
		}
		return true;
	}

}

H. 回忆迷宫

在这里插入图片描述

时间能力有限,今年难度明显增加,实在没时间去做

I. 红绿灯

在这里插入图片描述
时间能力有限,今年难度明显增加,实在没时间去做

J. 拉箱子

在这里插入图片描述
时间能力有限,今年难度明显增加,实在没时间去做

个人总结

这次应该是自己大学生涯里面的最后一次蓝桥杯了。

大一,大学里的第一次蓝桥杯是在大一的时候,第一次接触蓝桥杯的时候,感觉是真的很难,很多的算法自己听都没听说过,更别说去用了。当时参加的是C/C++,也是因为疫情在家,所以自己能有充足的时间去学习自己喜欢的技术,沉下心来练习算法题。当时那一届C/C++明显也比较简单,所以自己能做的都做出来了,最终拿了个省二,对于刚进入大学压根没接触过编程的我,在大一能拿到蓝桥杯省二给了我极大的自信。

大二,在大二的时候自己毫不犹豫继续报了蓝桥杯Java,当时也是练了很多题,但是在最后比赛的一个月,由于返校上课时间紧张,当时也作为队长和朋友们参加了其它几个比赛,正好也赶上当时那几个比赛的各种答辩,所以最后一个月练题数几乎为0,等到正式比赛的前一天晚上也才发现自己准考证也没打印,当时也比较慌,晚上睡觉也没睡好,所以第二天比赛个人就很迷,第一道编程题都没做出来,唉,或许万事不可能同时都做到最好吧,最终比赛也只拿到了省二,这次的省二反而让我很遗憾。

大三,课程少了,也没心思再去参加其它比赛,同时也要开始准备考研,但是想到自己大学生涯在蓝桥杯上的遗憾,选择再一次参加蓝桥杯,这一次,拼劲全力,从第6届开始,每一年的真题都来来回回刷了一遍,算法很美课程也跟着刷了一遍,所有例题思路都跟着做了一遍总结。3月月末,我们学校Java组选择退赛的就有2/3,个人感觉这次的压力明显变大,加上疫情,这次又导致线上比赛。。。

最后只能用一句话描述我与蓝桥杯:遇见蓝桥遇见你,不负代码不负卿。蓝桥杯是我大学竞赛的起点,同时也是我竞赛的终点。

  • 69
    点赞
  • 310
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 36
    评论
蓝桥杯是一个国内著名的计算机比赛,为了帮助参赛者更好地准备和了解比赛的题型,委会会公布历年的真题并提供相应的题解。 首先,我们需要了解蓝桥杯是一个综合性的计算机比赛,测试的对象包括计算机基础知识、编程能力以及解决实际问题的能力。 在历年的真题中,参赛者将面临不同类型的题目,包括算法设计与优化问题、数据结构算法问题、编程题等。其中针对Python B的题目主要考察的是对Python语言的掌握和应用能力。 题目解答一般会包含以下几个方面的内容: 1. 题目分析与理解:读取题目,理解题目的要求和限制条件。通过仔细分析题目,确定题目的输入与输出,以及问题的核心。 2. 设计解决方案:根据题目要求和限制条件,设计一个合适的解决方案。可以使用合适的算法数据结构来解决问题,并做出相应的性能优化。 3. 编写代码实现:根据设计的方案编写相应的代码实现。需要注意的是,Python语言有其独特的语法和特性,掌握好这些特性可以更好地完成编程任务。 4. 调试与测试:编写完代码后,需要进行调试和测试。通过运行样例输入和输出,检查代码是否符合题目要求,并且没有逻辑上的错误。 5. 总结与优化:在完成题目解答后,可以进行总结和优化。包括分析算法复杂度、代码风格和可读性等方面,以便在比赛中更好地表现。 在准备蓝桥杯时,可以通过阅读历年的真题和题解来了解比赛的难度和类型,针对性地进行练习和提高。同时也可以参加相关的培训班和讨论活动,与其他参赛者交流经验和技巧。 总而言之,历年蓝桥杯真题的解答对于提高自己的编程能力和应对比赛非常有帮助。通过认真分析和实践,可以更好地理解并掌握Python编程,并在比赛中取得更好的成绩。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梦码城

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

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

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

打赏作者

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

抵扣说明:

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

余额充值