第十一届蓝桥杯(10月)------java组B组,自己的一些理解

试题 A: 门牌制作(难度:★)5分

思路:

代码:

答案:

试题 B: 寻找 2020(难度:★★)5分

思路:

代码:

答案:

试题 C: 蛇形填数(难度:★★★)10分

思路:

代码:

答案:

试题 D: 七段码(难度:★★★)10分

思路:

代码:

答案:

试题 E: 排序(难度:★★★★)15分

思路:

代码:

答案:

试题 F: 成绩分析(难度:★)15分

思路:

代码:

试题 G: 单词分析(难度:★★)20分

思路:

代码:

试题 H: 数字三角形(难度:★★★★)20分

思路:

代码:

试题 I: 子串分值和(难度:★★★★★)25分

思路:

代码:

试题 J: 装饰珠(难度:★★★★★)25分

思路:

代码:

试题 A: 门牌制作(难度:★)5分

试题 A: 门牌制作 本题总分:5 分
【问题描述】
小蓝要为一条街的住户制作门牌号。 这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。 小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字 符粘贴到门牌上,例如门牌 1017
需要依次粘贴字符 1、0、1、7,即需要 1 个 字符 0,2 个字符 1,1 个字符 7。 请问要制作所有的 1 到 2020号门牌,总共需要多少个字符 2?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路:

从1到2020所有数字一共包含了多少个“2”。通过拼串查找字符并计数可获取。

代码:

public class Main {

	public static void main(String[] args) {
		int count = 0;
		for(int i = 1;i<=2020;i++){
			String s = i+"";
			for(int j = 0;j<s.length();j++){
			if(s.charAt(j)=='2')
				count++;
			}
		}
		System.out.println(count);

	}

}

答案:624

试题 B: 寻找 2020(难度:★★)5分

【问题描述】 小蓝有一个数字矩阵,里面只包含数字 0 和 2。小蓝很喜欢 2020,他想找 到这个数字矩阵中有多少个2020。小蓝只关注三种构成 2020 的方式:同一行里面连续四个字符从左到右构成 2020。同一列里面连续四个字符从上到下构成2020。 在一条从左上到右下的斜线上连续四个字符,从左上到右下构成 2020。 例如,对于下面的矩阵:
220000
000000
002202
000000
000022
002020

一共有 5 个 2020。其中 1 个是在同一行里的,1 个是在同一列里的,3 个是斜线上的。
小蓝的矩阵比上面的矩阵要大,由于太大了,他只好将这个矩阵放在了一 个文件里面,在试题目录下有一个文件2020.txt,里面给出了小蓝的矩阵。
请帮助小蓝确定在他的矩阵中有多少个 2020
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分

txt:
txt文件

思路:

把文件当做输入存入数组,文件中的行数和对应字符串数组的下标相对应,通过读取数组下标匹配字符串获取“2020”的数目。
首先对于txt文档,我们需要知道行数是多少,复制txt文件直接到ecalipse,利用ecaplise行号显示,可得知txt文件一共有300行。在这里插入图片描述
对于ecalipse行号开启方式: Ctrl+F10 勾选“show line numbers”
在这里插入图片描述

代码:

import java.util.Scanner;

public class Main {

	public static long count;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String[] str = new String[300];
		for(int i=0;i<300;i++)
		{
			str[i] = sc.nextLine();
		}
		sc.close();
		f(str);
		System.out.println(count);
		sc.close();
	}
	public static void f(String[] str)
	{
		for(int i=0;i<str.length;i++)
		{
			for(int j=0;j<str[i].length();j++)
			{
				if(str[i].charAt(j)=='2')//开头一定是2
				{
					//横向
					if(str[i].length()-j>=4 && str[i].charAt(j+1)=='0' && str[i].charAt(j+2)=='2' && str[i].charAt(j+3)=='0')
						count++;
					//竖向
					if(str.length-i>=4 && str[i+1].charAt(j)=='0' && str[i+2].charAt(j)=='2' && str[i+3].charAt(j)=='0')
						count++;
					//斜向
					if(str[i].length()-j>=4 && str.length-i>=4 && str[i+1].charAt(j+1)=='0' && str[i+2].charAt(j+2)=='2' && str[i+3].charAt(j+3)=='0')
						count++;
				}
			}
		}
	}

}

答案:16520

试题 C: 蛇形填数(难度:★★★)10分

【问题描述】
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 …
3 5 8 14 …
4 9 13 …
10 12 …
11 … … 容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20
列 的数是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路:

在这里插入图片描述
由图中顺序,顺着箭头方向,即蛇形整数排列的依据,按照箭头所指,第一行一个数,第二行两个数,第三行三个数…按照上述推理即可得到。

代码:

答案:761

试题 D: 七段码(难度:★★★)10分

【问题描述】
小蓝要用七段码数码管来表示一种特殊的文字。
在这里插入图片描述
上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二极管,分别标记为 a, b, c, d, e, f, g。 小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。 例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。
这种方案与上 一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c,d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路:

若没有后续条件,只求得七段码数码管能够表示的字符,把七段码a,b,c,d,e,f,g发光记做1,不发光记做0。则共有(2^7-1)种可能性,即共可以表达127中字符。加上后续条件,只需要枚举这127中字符,挨个看是否连通即可。

代码:

枚举127中类型如下,一 一对照即可。
1、输出枚举的127中0,1表示的数字

public class Text {
	public static void main(String[] args) {
	int a[] = new int[128];
		for(int i = 1;i<128;i++) {
			a[i] = Integer.parseInt(Integer.toBinaryString(i));
//			首先将十进制转换为二进制,因为Integer.toBinaryString()函数返回的是String类型
//			所以再用Integer.parseInt()函数转换成十进制(或者说是转换成int类型)重新存储进数组
		}
		for(int i = 0;i<128;i++) {
			System.out.printf("%07d",a[i]);
//			利用整形宽度,输出七位代表状态码的数字
			System.out.println();
		}		
	}
}

2、将上述输出的0,1作为输入内容,输出替换成字母的结果进行一一对比。

import java.util.Scanner;

public class T {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		char c[] = {'a','b','c','d','e','f','g'};
		String a[] = new String[128];
		for(int i = 1;i<128;i++) {
			a[i] = sc.nextLine();
		}
		for(int i = 1;i<128;i++) {
			for(int j = 0;j<a[i].length();j++) {
				if(a[i].charAt(j)=='1') {
					System.out.print(c[j]);
				}
			}
			System.out.println();
		}
		
	}

}

答案:80

试题 E: 排序(难度:★★★★)15分

【问题描述】
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。 在冒泡排序中,每次只能交换相邻的两个元素。小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符, 则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串 lan 排序,只需要 1 次交换。对于字符串 qiao 排序, 总共需要 4 次交换。
小蓝找到了很多字符串试图排序,他恰巧碰到一个字符串,需要 100 次交 换,可是他忘了吧这个字符串记下来,现在找不到了。
请帮助小蓝找一个只包含小写英文字母且没有字母重复出现的字符串,对 该串的字符排序,正好需要 100 次交换。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中不可以包含相同的字符。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个只包含小写英文字母的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。

思路:

冒泡排序,要求字符串最短,假设完全逆序,设长度为n,则移动次数最大次数为 n*(n-1)/2。


为什么是n*(n-1)/2呢?原因是这样,我们知道冒泡排序是把数字与相邻的数字比较,把最大的冒泡到最后边。
这里,我们假设这串的长度为n,交换次数最大,即每个数字都需要与相邻的数字交换,从左往右数串的第一位开始冒泡,第一位交换的次数为(n-1)第二位交换的次数为(n-2)…一直到最后一位,交换的总次数为:(n-1)+(n-2)+(n-3)+…+(n-(n-1))= [1+(n-1)]*(n-1)/2


要求移动次数恰好大于100,当n=14时,移动次数为91,当 n=15时,移动次数为105。故确定串长为15个字符。
元素不重复,那么15个字符为abcdefghijklmno
当串为onmlkjihgfedcba时,交换的次数为105次
要求字典序最小,移动100次。
则把第六个字符移动到第一个位置,前五个字符后移一位。

代码:

答案:jonmlkihgfedcba

试题 F: 成绩分析(难度:★)15分

【问题描述】
小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是 一个 0 到 100 的整数。请计算这次考试的最高分、最低分和平均分。
【输入格式】
输入的第一行包含一个整数 n,表示考试人数。 接下来 n 行,每行包含一个 0 至100 的整数,表示一个学生的得分。
【输出格式】
输出三行。
第一行包含一个整数,表示最高分。
第二行包含一个整数,表示最低分。
第三行包含一个实数,四舍五入保留正好两位小数,表示平均分。
【样例输入】
7
80
92
56
74
88
99
10
【样例输出】
99
10
71.29
【评测用例规模与约定】
对于 50% 的评测用例,1≤n≤100。
对于所有评测用例,1≤n≤10000。

思路:

累计,排序,求和,输出最大值,最小值,以及求和/数据个数。值得注意的是平均数包里两位小数。用printf("%.2f",sum/n)

代码:

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner (System.in);
		int n = sc.nextInt();
		double sum = 0;
		int a[] = new int[n];
		for(int i = 0;i<n;i++){
			a[i] = sc.nextInt();
			sum+=a[i];
		}
		Arrays.sort(a);
		System.out.println(a[n-1]);
		System.out.println(a[0]);
		System.out.printf("%.2f",sum/n);
	}

}

试题 G: 单词分析(难度:★★)20分

【问题描述】
小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不 住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这 个字母出现的次数。
【输入格式】
输入一行包含一个单词,单词只由小写英文字母组成。
【输出格式】
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪个。如果有多个字母出现的次数相等,输出字典序最小的那个。 第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。
【样例输入】
lanqiao
【样例输出】
a 2
【样例输入】
longlonglongistoolong
【样例输出】
o 6
【评测用例规模与约定】
对于所有的评测用例,输入的单词长度不超过 1000。

思路:

制作字典,制作与字典对应的包含26个字母的数组,输入字符串,挨个读取字符串中每一个字符,出现的次数存储进与字典对应的包含26个字母的数组,输出数组下标对应字典的字母以及数组的内容。

代码:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner (System.in);
		String s = sc.nextLine();
		int max = 0;
		int index = 0;
		String a = "abcdefghijklmnopqrstuvwxyz";
		int b[] = new int[26];
		
		for(int i = 0;i<s.length();i++){
			b[a.indexOf(s.charAt(i))]++;			
		}
		for(int j = 0;j<b.length;j++){
			if(b[j]>max){
				max = b[j];
				index = j;
			}
				
		}
		System.out.println(a.substring(index,index+1));
		System.out.println(max);
		
	}

}

有点事,回来再写

试题 H: 数字三角形(难度:★★★★)20分

【问题描述】
在这里插入图片描述

上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。 对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过1。
【输入格式】
输入的第一行包含一个整数 N (1 < N ≤ 100),表示三角形的行数。下面的 N行给出数字三角形。
数字三角形上的数都是 0 至 100 之间的整数。
【输出格式】
输出一个整数,表示答案。
【样例输入】
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
【样例输出】
27

思路:

DP推导+奇偶判断。在输入数组的时候进行数组值的计算,因为只能向左或者右走,即我现在所在的位置坐标是从上一层这个位置的左边或者上边进行跳转得到的坐标,通过选择最大值进行跳转,更新数组的值,由于向左向右不能超过1,所以通过奇偶判断层数,如果是奇数,最后的位置第n层,第(n/2+1)位置上的数字,如果是偶数,则需要判断第n层,第(n/2)位置的数字和第n层第(n/2+1)位置的数字,选大的。
注意我的数组下标是从1开始。

代码:

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int arr[][]=new int[n+1][n+1];
		for(int i=1;i<=n;i++){
			for(int j=1;j<=i;j++){
				arr[i][j]=sc.nextInt();
				arr[i][j]+=Math.max(arr[i-1][j-1], arr[i-1][j]);
			}
		}
		System.out.println(n%2==1?arr[n][n/2+1]:Math.max(arr[n][n/2], arr[n][n/2+1]));
	}
}

试题 I: 子串分值和(难度:★★★★★)25分

【问题描述】
对于一个字符串 S,我们定义 S 的分值 f(S) 为 S 中出现的不同的字符个 数。
例如 f(”aba”) =2,f(”abc”) = 3, f(”aaa”) = 1。
现在给定一个字符串 S[0…n−1](长度为 n),
请你计算对于所有 S的非空 子串 S[i…j](0≤i≤ j < n),f(S[i…j]) 的和是多少。
【输入格式】
输入一行包含一个由小写字母组成的字符串 S。
【输出格式】
输出一个整数表示答案。
【样例输入】
ababc
【样例输出】 28
【样例说明】
子串 f值
a 1
ab 2
aba 2
abab 2
ababc 3
b 1
ba 2
bab 2
babc 3
a 1
ab 2
abc 3
b 1
bc 2
c 1
【评测用例规模与约定】
对于 20% 的评测用例,1≤n≤10;
对于 40% 的评测用例,1≤n≤100;
对于 50% 的评测用例,1≤n≤1000;
对于 60% 的评测用例,1≤n≤10000;
对于所有评测用例,1≤n≤100000。

思路:

将字符串从i,到j位进行分割,分割后的字串在进行去重,所有去重后字串的长度相加输出即可。

代码:

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner (System.in);
		String s = sc.nextLine();
		String a[] = new String[40000000];
		int k = 0;
		int count = 0;
		for(int i = 0;i<s.length();i++){
			for(int j = i+1;j<=s.length();j++){
				a[k] = (s.substring(i,j));
				k++;
			}		
		}
		for(int i = 0;i<k;i++){
			Set<String> set = new HashSet<String>();
			for(int j = 0;j<a[i].length();j++){
				set.add(a[i].charAt(j)+"");	
			}
			count = count+set.size();		
		}	
	System.out.print(count);	
	}

}

试题 J: 装饰珠(难度:★★★★★)25分

思路:

代码:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值