2019年 第十届蓝桥杯省赛题解(JavaB组版)
2020年 第十一届蓝桥杯第一场省赛题解(JavaB组版)
2020年 第十一届蓝桥杯第二场省赛题解(JavaB组版)
2020年 第十一届蓝桥杯第一场省赛题解(JavaC组版)
2021年 第十二届蓝桥杯第二期校内模拟赛题解(Java版)
文章目录
第一题:门牌制作
小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个 字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
答案:624
int sum=0;
for(int i=1;i<2021;i++) {
int j=i;
while(j>0) {
int yu=j%10;
j/=10;
if(yu==2)sum++;
}
}
System.out.println(sum);
第二题:寻找 2020
小蓝有一个数字矩阵,里面只包含数字 0 和 2。小蓝很喜欢 2020,他想找到这个数字矩阵中有多少个 2020 。
小蓝只关注三种构成 2020 的方式:
• 同一行里面连续四个字符从左到右构成 2020。
• 同一列里面连续四个字符从上到下构成 2020。
• 在一条从左上到右下的斜线上连续四个字符,从左上到右下构成 2020。
例如,对于下面的矩阵:
220000
000000
002202
000000
000022
002020
一共有 5 个 2020。其中 1 个是在同一行里的,1 个是在同一列里的,3 个是斜线上的。
小蓝的矩阵比上面的矩阵要大,由于太大了,他只好将这个矩阵放在了一个文件里面,在试题目录下有一个文件 2020.txt,里面给出了小蓝的矩阵。
输入文件
答案: 16520
法一:控制台输入
Scanner scanner=new Scanner(System.in);
String[] str=new String[300];
for(int i=0;i<300;i++) {
str[i]=scanner.next();//输入字符
}
char[][] cs=new char[300][300];
for(int i=0;i<300;i++)
cs[i]=str[i].toCharArray();//转成char字符
int count=0;
for(int i=0;i<cs.length;i++) {
for(int j=0;j<cs[i].length;j++) {
if(cs[i][j]=='2') {//三种情况判断还得判断下标越界不
if(j+3<cs[i].length&&cs[i][j+1]=='0'&&cs[i][j+2]=='2'&&cs[i][j+3]=='0')count++;
if(i+3<cs.length&&cs[i+1][j]=='0'&&cs[i+2][j]=='2'&&cs[i+3][j]=='0')count++;
if(j+3<cs[i].length&&i+3<cs.length&&cs[i+1][j+1]=='0'&&cs[i+2][j+2]=='2'&&cs[i+3][j+3]=='0')count++;
}
}
}
System.out.println(count);
法二:IO流读取
BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream("E:\\2020.txt")));
String[] str=new String[300];
int k=0;
while(reader.ready()) {//告诉这个流是否准备好被读取 结果
//如果下一个read()保证不阻止输入,则为True,否则为false。 请注意,返回false并不能保证下一次读取将被阻止。
str[k]=reader.readLine();//读一行文字
k++;
}
/* while((str[k]=reader.readLine())!=null) {//这种要开301,str[301]="";
k++;
}*/
第三题:蛇形填数
如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 ...
3 5 8 14 ...
4 9 13 ...
10 12 ... (1)
11 ...
...
容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列的数是多少?
答案: 761
//对角线的值等于该值的平方+上一个值的平方
System.out.println(20*20+19*19);//找规律即可
第四题:七段码(未解)
小蓝要用七段码数码管来表示一种特殊的文字。
上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二 极管,分别标记为 a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符 的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光 的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?
答案: 80(暂时不会)
第五题:排序
小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。在冒泡排序中,每次只能交换相邻的两个元素。
小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串 lan 排序,只需要 1 次交换。对于字符串 qiao 排序,总共需要 4 次交换。
小蓝找到了很多字符串试图排序,他恰巧碰到一个字符串,需要 100 次交换,可是他忘了吧这个字符串记下来,现在找不到了。
请帮助小蓝找一个只包含小写英文字母且没有字母重复出现的字符串,对该串的字符排序,正好需要 100 次交换。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中不可以包含相同的字符。
答案:
第六题:成绩分析
小蓝给学生们组织了一场考试,卷面总分为 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。
答案:
/* * 简单的求值问题
* 坑点:1.数组多,会越界得用long存取
* 2.String.format("%.2f",a)保留2位小数并且能够四舍五入*/
int N=10000 ;
int[] arr=new int[N];
long min=Integer.MAX_VALUE,max=Integer.MIN_VALUE;
double avg=0;
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
for(int i=0;i<n;i++) {
arr[i]=scanner.nextInt();
min=Math.min(arr[i], min);
max=Math.max(arr[i], max);
avg+=arr[i];
}
avg=avg/n;
System.out.println(max);
System.out.println(min);
System.out.println(String.format("%.2f",avg));
第七题:单词分析
小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组 成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不 住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得 最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这 个字母出现的次数。
输入格式:
输入一行包含一个单词,单词只由小写英文字母组成。
输出格式:
输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪 个。如果有多个字母出现的次数相等,输出字典序最小的那个。
样例输入:
lanqiao
样例输出:
a
2
样例输入:
longlonglongistoolong
样例输出:
o
6
评测用例规模与约定:
对于所有的评测用例,输入的单词长度不超过 1000。
答案:
//用哈希表计算即可
//坑点:注意不要看漏题意(如果有多个字母出现的次数相等,输出字典序最小的那个。)这限制条件很常见
//System.err:“标准”错误输出流
Scanner scanner=new Scanner(System.in);
int[] hash=new int[1010];
String string=scanner.next();
int idx = 0;
int max=0;
for(int i=0;i<string.length();i++) {
int j=string.charAt(i)-0;//把a=48的转为数字表示
hash[j]++;//该字母的hash值加一
if(max<hash[j]||max==hash[j]&&idx>j) {
max=hash[j];
idx=j;//出现最多的字母下标
}
}
System.out.println((char)idx);//把数字转为字母
System.out.println(max);
第八题:数字三角形
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 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题
//线性DP
Scanner scanner=new Scanner(System.in);
int N=110;
int[][] g=new int[N][N];//容量比数据要求的大一些
int[][] f=new int[N][N];//表示所有从(1,1)走到(i,j)的合法路线集合,值存储的是所有路线中和最大的
int n=scanner.nextInt();
for(int i=1;i<=n;i++) {
for(int j=1;j<=i;j++) {
g[i][j]=scanner.nextInt();
}
}
for(int i=0;i<N;i++) {
for(int j=0;j<N;j++)
f[i][j]=Integer.MIN_VALUE;//题目求最大值,先初始化为最小值(表示负无穷),同时可以表示边界
}
f[1][1]=g[1][1];
for(int i=2;i<=n;i++) {
for(int j=1;j<=i;j++) {
//最好情况下可以从两个地方走,也有可能只能一个地方走到,另一个不存在但没关系,不存在的已经初始为最小值不会取到
f[i][j]=Math.max(f[i-1][j-1], f[i-1][j])+g[i][j];
}
}
//由于题目是说向左下走的次数与向右下走的次数相差不能超过 1。说明最后一步必须是底层的中位数
if(n%2==0)System.out.println(Math.max(f[n][n/2], f[n][n/2-1]));//比较偶数个的两个中间数
else System.out.println(f[n][n/2+1]);//奇数只有一个
第九题:子串分值和
对于一个字符串 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。
答案:
//只想到用hashset去重,时间复杂n^2,会超时不过一半分拿下也不错了
Scanner sc = new Scanner(System.in);
String string=sc.next();
int res=0;
for(int i=0;i<string.length();i++) {//字串起点
HashSet<Character> hashSet=new HashSet<>();//可以去重
for(int j=i;j<string.length();j++) {
hashSet.add(string.charAt(j));
res+=hashSet.size();//去重后的个数就是分数
}
}
System.out.println(res);
第十题:装饰珠(未解)
输出格式
输出一行包含一个整数,表示能够得到的最大价值。
【样例输入】
1 1
2 1 2
1 1
2 2 2
1 1
1 3
3
1 5 1 2 3 5 8
2 4 2 4 8 15
3 2 5 10
样例输出
20
样例说明
按照如下方式镶嵌珠子得到最大价值 18,括号内表示镶嵌的装饰珠的
种类
编号:
1: (1)
2: (1) (2)
3: (1)
4: (2) (2)
5: (1)
6: (2)
4 颗技能 1 装饰珠, 4 颗技能 2 装饰珠 W1(4) + W2(4) =
5 + 15 = 20。
评测用例规模与约定
对于 30% 的评测用例, 1 ≤ Ni ≤ 10, 1 ≤ M ≤ 20, 1 ≤ Wj(k) ≤ 500;
对于所有评测用例, 1 ≤ Ni ≤ 50, 1 ≤ M ≤ 10000, 1 ≤ Wj(k) ≤ 10000。
答案:
超级复杂的DP,果断放弃