欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

第十二届蓝桥杯Java省赛B组部分真题解析

时间:2023-06-18
第一题:Char(送分题)

  char类型以ASCAII值存储,1-9(48~57)、A~Z(65~90)、a-z(97~122)


第二题:卡牌(送分题,一个顺序循环就可以出来了)

package Test;public class Main {public static void main(String[] args) {int a=0,b=0,c=0,d=0,e=0,f=0,g=0,l=0,m=0,n=0;int sum=1;while(true) {String k = String.valueOf(sum);char[] p=k.toCharArray();int size=p.length;if(k.contains("0")) {for(int t=0;t2021||b>2021||c>2021||d>2021||e>2021||f>2021||g>2021||l>2021||m>2021||n>2021) break;sum++;}System.out.print(sum-1);}}


第三题:直线(需要仔细处理ABC的成倍数出现的情况)

思路:先用一个循环把所有的点的坐标放在一个数组里面,我这里用的List(好处是不用设定大小)。然后对list里面的每一个值循环访问其他值(即取出两个不同点坐标(x1,y1)(x2,y2)),通过直线的一般式Ax+By+C=0得到A=y2-y1,B=x1-x2,C=x2*y1-x1*y2,对ABC的组合消除倍数关系加入到泛型集合中,因为set的自动去重只对基本类(比如String,Integer等)有效,然后输出set.size().

import java.util.*;public class X {public static void main(String[] args) {Set set=new HashSet();List list = new ArrayList();for(int i=0;i<20;i++) {for(int j=0;j<21;j++) {list.add(String.valueOf(i)+"|"+String.valueOf(j));}}for(int i=0;i


第四题:因子的排列组合

这里看起来好像很简单:两个for循环从1到N,如果N%(i*j)==0 sum++的思路不是不可以,但是复杂度太高了,对于一个长整型的数据,跑一遍for需要好久,何况两遍?于是这题我和电脑对着坐牢,几个小时都没结果的那种。看有些人的处理是从质数因子组合去写,额...即任何一个数都可以拆分成质因子的组合,然后排列组合,算了,跳过吧,我宁愿坐牢


第五题:最短路(最简单的情况,直接Floyd)

思路:对于这2021个点我们建立一个2022*2022的二维数组作为带权的邻接矩阵,权值为lcm()

public class Floyd {public static void main(String[] args) {int[][] Linjie =new int[2022][2022];for(int i=1;i<=2021;i++) {for(int j=i+1;j<=Math.min(2021-i,21)+i;j++) {Linjie[i][j]=Linjie[j][i]=lcm(j,i);}}for(int i=1;i<=2021;i++) {for(int j=1;j<=2021;j++) {if(Linjie[i][j]==0) continue;for(int k=1;k<=2021;k++) {if(Linjie[k][i]==0) continue;else if(Linjie[j][k]==0||Linjie[j][k]>Linjie[i][j]+Linjie[k][i]) Linjie[j][k]=Linjie[i][j]+Linjie[k][i];}}}System.out.print(Linjie[1][2021]);}private static int lcm(int j, int i) {return (i*j)/gcd(j,i);}private static int gcd(int j, int i) {return i==0?j:gcd(i,j%i);}}


第六题:时间转换(送分题,注意是ms,使用前先除以1000,一天86400s,一个小时3600s,一分钟60s,知道这些就可以套用/和%的组合得出结果了)

import java.util.Scanner;public class Time {public static void main(String[] args) {Scanner time =new Scanner(System.in);long t= time.nextLong()/1000;long duo=t%86400;long H =duo/3600;long M =duo%3600/60;long S =duo%3600%60;String h=String.valueOf(H);String m=String.valueOf(M);String s=String.valueOf(S);if(H<10) h="0"+h;if(M<10) m="0"+m;if(S<10) s="0"+s;System.out.print(h+":"+m+":"+s);}}


第七题:砝码

    找规律题目,规律就是从1开始,每加一次砝码所表示的最大范围为3*n+1,数列左开右闭:为1  4  13  40 121...也就是说在2~4<1 3>之间用2个就可以表示,5~13之间用3个<1 3 9>就可以表示 ,14~40用4个表示<1 3 9 27> ,那么3*n+1怎么推出来的呢,其实也不是很难想出来,当N=1的时候 用一个砝码,重量为1,当N=2的时候,用两个砝码,重量为1和2,但是我想N=4的时候重量为1和4就表示不出来2,但是取1和3就可以连续的表示出1-4中的每一种数,于是3这个数就定下来了,定下来这两个砝码的重量后我发现现在我可以表示1-4的任何数据,依此递推到N=5时我无法表示,所以我只能继续加砝码,为了扩大表示范围,我将第三个砝码的重量定为9.这里说一下,为什么是9而不能是8或者10或者其他的呢。因为我们以前拥有的两个砝码已经可以表示1-4,如果我们将1-4作为下一个砝码的减法,那么这个砝码最大不超过9,因为如果第三个砝码重为10,那么10-4=6(最多只能减到6),无法表示出5,于是第三个砝码的重量定为9,因为9可以加上或者减去前面的范围值,那么所表示的范围也从1-4变为1-13,依次类推,这个范围变成了下个砝码的减法,于是这个砝码的重量为13+13+1=27,所表示的范围为13+13+1+13=40,这个更大的范围(1-40)其实是前一个范围(1-13)的三倍多1。

import java.util.*;public class M {public static void main(String[] args) {Scanner sc =new Scanner(System.in);int N =sc.nextInt();int sum=1,num=1;while(true) {if(num>=N) break;num=num*3+1;sum++;}System.out.print(sum);}}


第八题:杨辉三角(送分题)

真不是我说第7题需要想一想规律,前三个编程题目就有两个送的?

import java.util.Scanner;public class Yanghui { static int[][] k = new int[100][100];public static void main(String[] args) {//杨辉三角本来是金字塔形,但是为了方便我们把他变成半三角形(直角在左下角),根据规律第一列全为1,斜边也全是1,其他的数据k[i][j]等于k[i-1][j]+k[i-1][j-1] Scanner r =new Scanner(System.in); int N =r.nextInt();for(int i=0;i<100;i++) {for(int j=0;j<=i;j++) {k[i][j]=1;}}for(int i=2;i<100;i++) {for(int j=1;j


第九题:排列数组

这种题目无脑暴力解决,得到一部分分数真的太简单

import java.util.*;public class Xu {public static void main(String[] args) {Scanner s = new Scanner(System.in);int n=s.nextInt(); //一共N个数字1-nint m=s.nextInt(); //操作次数 int[] N =new int[n+1];for(int i=1;i<=n;i++) {N[i]=i;}int[][] k = new int[m+1][2];for(int i=1;i<=m;i++) {for(int j=0;j<=1;j++) {k[i][j]=s.nextInt();}}for(int i=1;i<=m;i++) {if(k[i][0]==0) {for(int j=1;j<=k[i][1];j++) {int max=N[j];for(int l=j+1;l<=k[i][1];l++) {if(N[l]>max) {max=N[l];int p=N[j];N[j]=N[l];N[l]=p;}}}}else {for(int j=k[i][1];j<=n;j++) {int min=N[j];for(int l=j+1;l<=n;l++) {if(N[l]


第十题:括号纠正

我只能说编程不复杂但是很费时间,因为要处理的情况有点多。首先对字符串里面的"("和")"的数量做提取,如果左括号多于右括号,多几个就要插几个右括号(还是暴力~嵌套n重循环,利用递归去嵌套,因为n是变量,他根据括号差来嵌套的),同理,如果右括号多了,多几个右括号就要插入几个左括号,如果一样多,首先将这个字符串里面成对出现的“()”做一个删除直到没有“()”出现,比如原来的括号情况为)(())(,处理后为)(,对这种再进行处理,也是暴力~嵌套n重循环~递归嵌套,嵌套的层数为处理后的字符串的长度,n重循环对应着n个插入点去插入括号,利用递归的思想最后根据位置索引列表去插字符串,然后判断是否合格,就是对插入后的字符串去()化,直到字符串为空字符串(长度小于1)就是合格的字符串然后加入到set去重

这里需要注意一些:字符串的插入属于StringBuffer的操作,插入和删除都会对源字符串进行破坏,所以在操作之前可以new一个新的StringBuffer去操作,保留字符串的完整性

import java.util.*;import java.util.Scanner;import java.util.Set;public class Kuohao {static String str="(";static Set set = new HashSet();static List list = new ArrayList();public static void main(String[] args) {Scanner s = new Scanner(System.in);String n=s.next();char[] ch = n.toCharArray();int Left=0,Right=0,dif=0;for(int i=0;iRight) {dif=Left-Right;str=")";} if(Left

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。