2020蓝桥杯省赛Java B组一等奖

大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn


A 门牌制作

本题总分:5 分

问题描述

小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字
符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个
字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

624

代码

/*
 * @Author: motongxue
 * @Date: 2020-10-13 20:39:33
 * @LastEditTime: 2020-10-28 20:37:33
 * @Blog: https://motongxue.cn
 */
public class Main {
    public static int getNum(int n) {
        int res = 0;
        while (n != 0) {
            if (n % 10 == 2)
                res++;
            n = n / 10;
        }
        return res;
    }

    public static void main(String[] args) {
        int res = 0;
        for (int i = 1; i <= 2020; i++) {
            res += getNum(i);
        }
        System.out.println(res);
    }
}

纯水题

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。

答案提交

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

16520

分析

这道题最大的问题应该不是判断相连是否能得到2020,很多人卡壳的地方应该是怎么读入那么大的矩阵。
实际上,Java有很方便的读取文件的方式。Scanner sc = new Scanner(new File("2020.txt"));读取后存为字符数组判断就行了。

C 蛇形填数

本题总分:10 分

问题描述

如下图所示,小明用从 1 开始的正整数“蛇形”填充无限大的矩阵。

1 2 6 7 15 ...
3 5 8 14 ...
4 9 13 ...
10 12 ...
11 ...
...

容易看出矩阵第二行第二列中的数是 5。请你计算矩阵中第 20 行第 20 列
的数是多少?

答案提交

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

761

分析

实际上,有两种方法

  1. 朴素方法,求出每一斜行的末尾数字,然后根据行数奇偶性推出每一斜行的第一个元素或者最后一个元素,然后倒推出来就行。
  2. 根据对角线元素变化规律,1 -> 5 -> 13 求出第20行20列的元素大小(推荐)

考场上没想着找规律,就用了第一种憨憨办法

代码

public class Main {

    public static void main(String[] args) {
        int[][] mp = new int[201][201];
        int n = 0;
        for (int k = 1; k <= 200; k++)
            if (k%2==1)
                for (int i = k; i >= 1; i--)
                    mp[i][k - i + 1] = ++n;
            else
                for (int i = 1; i <= k; i++)
                    mp[i][k - i + 1] = ++n;
        System.out.print(mp[20][20]);
    }
}

D 七段码

本题总分:10 分

问题描述

小蓝要用七段码数码管来表示一种特殊的文字。
在这里插入图片描述

上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二
极管,分别标记为 a, b, c, d, e, f, g。
小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符
的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上
一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光
的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?

答案提交

这是一道结果填空题,你只需要算出结果后提交即可。本题的结果为一个
整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

分析

80
考完出来才想着得用递归。
考场上直接用优化全排列去重,求出每一种组合。然后再转换成图像,人眼判断。答案也是80
下面借鉴了别人的代码。

代码

import java.util.Arrays;

public class Main {

    static int cnt;
    static boolean[] select, marked, graph[];

    public static void main(String[] args) {
        select = new boolean[7];
        marked = new boolean[7];
        graph = new boolean[7][7];
        graph[0][1] = graph[1][0] = true;
        graph[0][5] = graph[5][0] = true;
        graph[1][6] = graph[6][1] = true;
        graph[1][2] = graph[2][1] = true;
        graph[2][6] = graph[6][2] = true;
        graph[2][3] = graph[3][2] = true;
        graph[3][4] = graph[4][3] = true;
        graph[4][5] = graph[5][4] = true;
        graph[4][6] = graph[6][4] = true;
        graph[5][6] = graph[6][5] = true;
        dfs(0, 0);
        System.out.print(cnt);
    }

    static void dfs(int d, int len) {
        if (d == 7) {
            if (len == 0) return;
            int v = 0;
            while (!select[v]) v++;
            Arrays.fill(marked, false);
            if (findPath(v) == len) cnt++;
        } else {
            select[d] = true;
            dfs(d + 1, len + 1);
            select[d] = false;
            dfs(d + 1, len);
        }
    }

    static int findPath(int v) {
        marked[v] = true;
        int len = 1;
        for (int w = 0; w < 7; w++) {
            if (!select[w] || marked[w] || !graph[v][w]) continue;
            len += findPath(w);
        }
        return len;
    }
}

因为这个图存在环,所以不能正常回溯,但全排列下来也只有 127 种组合,索性就不回溯了

E 排序

本题总分:15 分

问题描述

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

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个只包含小写英文字母的字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。

分析

首先确定范围,冒泡交换的次数是根据逆序数来看的,要交换100次的话,元素个数必须大于等于15个
最开始想着优化全排列,跑了很久还是没跑出,最后观察写了答案jonmlkihgfedcba就是把j提到最前。但答案存疑,欢迎大佬分享答案

F 成绩分析

时间限制: 1.0s 内存限制: 512.0MB 本题总分:15 分

问题描述

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是
一个 0 到 100 的整数。
请计算这次考试的最高分、最低分和平均分。

输入格式

输入的第一行包含一个整数 n,表示考试人数。
接下来 n 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。

输出格式

输出三行。
第一行包含一个整数,表示最高分。
第二行包含一个整数,表示最低分。
第三行包含一个实数,四舍五入保留正好两位小数,表示平均分。

Input:

7
80
92
56
74
88
99
10

Output:

99
10
71.29

评测用例规模与约定

对于 50% 的评测用例,1 ≤ n ≤ 100。
对于所有评测用例,1 ≤ n ≤ 10000。

分析

水题,数据规模也不大
不过这里介绍一个Java大量输入的模板StreamTokenizer可以称为令牌。直接背诵模板也行

StreamTokenizer in = new StreamTokenizer(new BufferedReader(new  InputStreamReader(System.in)));
in.nextToken();         // 默认读入为字符串
int n = (int)in.nval    //  可以转为其他类型

代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.### InputStreamReader;
import java.io.StreamTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new  InputStreamReader(System.in)));
        in.nextToken();
        int n = (int)in.nval, sum = 0, max = 0, min = 128;
        for (int i = 0, t; i < n; i++) {
            in.nextToken();
            sum += t = (int)in.nval;
            if (t > max) max = t;
            if (t < min) min = t;
        }
        System.out.printf("%d\n%d\n%.2f", max, min, (double)sum / n);
    }
}

G 单词分析

时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分

问题描述

小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组
成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不
住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得
最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这
个字母出现的次数。

输入格式

输入一行包含一个单词,单词只由小写英文字母组成。

输出格式

输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪
个。如果有多个字母出现的次数相等,输出字典序最小的那个。
第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。

Input:

lanqiao

Output:

a
2

Input:

longlonglongistoolong

Output:

o
6

评测用例规模与约定

对于所有的评测用例,输入的单词长度不超过 1000。

分析

一个数组判重的改编,我之前有很详细的写过。有兴趣的可以去我的博客里看一下

总体思路就是先存下标,然后再统计存进下标的次数

代码

import java.io.IOException;

public class Main {

    public static void main(String[] args) throws IOException {
        byte[] buff = new byte[1024];
        int l = System.in.read(buff), max = 0;
        int[] cnt = new int[128];
        for (int i = 0; i < l; i++)
            cnt[buff[i]]++;
        for (char i = 'z'; i >= 'a'; i--)
            if (cnt[i] >= max) {
                max = cnt[i];
                l = i;
            }
        System.out.println((char)l + "\n" + max);
    }
}

H 数字三角形

时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分

问题描述

在这里插入图片描述
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。
对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。
路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 1。

输入格式

输入的第一行包含一个整数 N (1 < N ≤ 100),表示三角形的行数。下面的
N 行给出数字三角形。数字三角形上的数都是 0 至 100 之间的整数

输出格式

输出一个整数,表示答案。

Input:

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

Output:

27
1
2
3
4
5
6
7
8
9
10

分析

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

时间限制: 1.0s 内存限制: 512.0MB 本题总分: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。

输出格式

输出一个整数表示答案。

Input:

ababc

Output:

28

Explanation:

子串 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。

分析

这道题纯暴力,能50、60分了,时间着急,在考场上就没优化

J 装饰珠

时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分

问题描述

在怪物猎人这一款游戏中,玩家可以通过给装备镶嵌不同的装饰珠来获取
相应的技能,以提升自己的战斗能力。
已知猎人身上一共有 6 件装备,每件装备可能有若干个装饰孔,每个装饰
孔有各自的等级,可以镶嵌一颗小于等于自身等级的装饰珠 (也可以选择不镶
嵌)。
装饰珠有 M 种,编号 1 至 M,分别对应 M 种技能,第 i 种装饰珠的等级
为 Li ,只能镶嵌在等级大于等于 L i 的装饰孔中。
对第 i 种技能来说,当装备相应技能的装饰珠数量达到 K i个时,会产生W i ( K i ) 的价值。镶嵌同类技能的数量越多,产生的价值越大,即 W i ( K i − 1 ) < W i ( K i ) 。但每个技能都有上限 P i ( 1 ≤ P i ≤ 7 ) ,当装备的珠子数量超过 P i时,只会产生 W i ( P i ) 的价值。
对于给定的装备和装饰珠数据,求解如何镶嵌装饰珠,使得 6 件装备能得
到的总价值达到最大。

输入格式

输入的第 1 至 6 行,包含 6 件装备的描述。其中第 i 的第一个整数 N i 表示
第 i 件装备的装饰孔数量。后面紧接着 N i 个整数,分别表示该装备上每个装饰
孔的等级 L ( 1 ≤ L ≤ 4 )。
第 7 行包含一个正整数 M ,表示装饰珠 (技能) 种类数量。
第 8 至 M + 7 行,每行描述一种装饰珠 (技能) 的情况。每行的前两个整数
L j ( 1 ≤ L j ≤ 4 )和 P j ( 1 ≤ P i ≤ 7 )分别表示第 j 种装饰珠的等级和上限。接下来
P j个整数,其中第 k 个数表示装备该中装饰珠数量为 k 时的价值 W j ( k ) 。

输出格式

输出一行包含一个整数,表示能够得到的最大价值。

Input:

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

Output:

20

Explanation:

按照如下方式镶嵌珠子得到最大价值 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。


2020年10月28日更

大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn


  • 21
    点赞
  • 142
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
山东蓝桥杯是一项具有较高知名度和竞争水平的计算机大,在Java组别中获得一等奖需要具备一定的实力和准备。以下是我个人认为要做对的几点: 首先,提前充分准备。蓝桥杯难度较高,考察的范围也较广,包括Java基础知识、算法与数据结构、面向对象编程等方面。因此,要通过自学、课程学习或参加相关培训,全面掌握Java语言的基础知识,并能运用到实际编程中。 其次,熟悉竞规则和题型。蓝桥杯的比形式多样,包括在线理论笔试、编程题、上机调试等环节。了解比的评分规则、答题时间和提交方式,合理分配时间,有针对性地备战每个环节,以最大程度地发挥自己的优势。 此外,要有实践经验和项目积累。蓝桥杯不仅要求理论知识的掌握,还注重对实际问题的解决能力。要积极参加项目实践,多从事项目开发,充分锻炼自己的编程思维和解决问题的能力。 还要通过做题训练提高编程能力。选取蓝桥杯历年的真题或类似题目进行模拟训练,通过不断练习来提高自己的编程能力和解题思路。在解题过程中,要注意代码的规范性、可读性和效率,注重算法优化和程序调试。 最后,保持积极的心态和团队合作精神。蓝桥杯是一次公平竞争,要有自信心和坚持不懈的努力,不怕困难和挫折。同时,要积极与队友合作,共同攻克问题,提高团队的整体水平。 总之,获得山东蓝桥杯Java一等奖需要全面准备,从基础知识学习到实际项目实践,再到解题训练和团队合作,都需要付出大量的努力和时间。只有真正理解并掌握了Java编程的本质,才能在竞中做对。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值