2020年蓝桥杯题目
前言 🔗
交了 300 不去感觉血亏,还是去参加吧…
滔博 🐮🍺 好吧,LPL 冲冲冲,预言一手 G2 爆冷干碎 LCK 哈哈哈哈哈
题目 🔗
门派制作 🔗
大意就是找出1 - 2020
中数字2
出现的个数
由于是填空题,直接遍历然后计算即可
public class Main {
public static void main(String[] args){
int count = 0;
for(int i = 1; i <= 2020; i++){
int num = i;
while(num > 0){
int rest = num % 10;
if(rest == 2){
count++;
}
num = num / 10;
}
}
System.out.println(count);
}
}
算出的答案为624
,这题其实在力扣上有基本一样的,可以直接遍历数位计算出来
有兴趣的可以做做,我就做了第二题,虽然是看着题解做的 🤣
基本思路就是把数字分成左右两半进行计算,从而以O(n)
复杂度(n
为数字长度)
在第一题的控制台试了试,输出了624
,那应该就是正确的
只能说暴力法天下第一好吧,只要我的电脑够快,复杂度就追不上我 🤣
找2020
🔗
大意就是给你一个数组,对下面三种情况计数
- 每行左到右出现
2020
- 每列上到下出现
2020
- 左上到右下对角线出现
2020
同样,由于是填空题,所以依然暴力(因为想不出其他解法了 🤣)
这一题给了个txt
文件,答的时候看了下,应该是300x300
的数组
刚开始我认为我写不出来文件的读取,没想到查了查 api 文档竟然写出来了 🤣
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class lanqiao_P2 {
public static void main(String[] args) {
String filePath = "D:\\2020.txt";
// 因为知道300x300了,这里就直接写死了。
int[][] array = new int[300][300];
int curLine = 0;
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));
String line = br.readLine();
while (line != null) {
// 防止空格
line = line.trim();
for (int i = 0; i < line.length(); i++) {
array[curLine][i] = line.charAt(i) - '0';
}
curLine++;
line = br.readLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally{
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
int count = 0;
// 遍历行
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length - 3; j++) {
if (array[i][j] == 2
&& array[i][j + 1] == 0
&& array[i][j + 2] == 2
&& array[i][j + 3] == 0) {
count++;
}
}
}
// 遍历列
for (int i = 0; i < array[0].length; i++) {
for (int j = 0; j < array.length - 3; j++) {
if (array[j][i] == 2
&& array[j + 1][i] == 0
&& array[j + 2][i] == 2
&& array[j + 3][i] == 0) {
count++;
}
}
}
// 遍历左上到右下
for (int i = 0; i < array.length - 3; i++) {
if (array[i][i] == 2
&& array[i + 1][i + 1] == 0
&& array[i + 2][i + 2] == 2
&& array[i + 3][i + 3] == 0) {
count++;
}
}
System.out.println(count);
}
}
这题忘了答案是啥来着了…
蛇形填空 🔗
大意就是,数字按下面的规律,求20
行20
列的数字
1 2 6 7 15 ...
3 5 8 14 ...
4 9 13 ...
10 12 ...
11 ...
...
这题我没写代码来计算,我看着规律的…
首先要确定20
行20
列最少要多少次蛇形
看样例可以知道
3
行3
列可以计算出2
行2
列
5
行5
列可以计算出3
行3
列
那么计算20
行20
列,应该需要39
行39
列,即20 * 2 - 1
然后又可以看出每次蛇形的结束的值就是累加1+2+...+n
的值
1 2 ...
3 ...
此时最后的值应该是 1 + 2 = 3
那么第39
次蛇形的结束的值应该就是1 + 2 + ... + 39 = 780
起始值应该就是 780 + 1 - 39 = 742
根据样例的规律,斜着的奇数行的结束是在第一行,斜着的偶数行的结束在第一列,也就是
1 2 6 7 15 ... 780
3 5 8 14 ... 779
4 9 13 ... 778
10 12 ... ...
11 ... 744
... 743
742
然后取中间的值,就是20
行20
列的值了,也就是761
(感觉是正确的…)
七段码 🔗
大意就是用发光二极管来表示字符串,问能表示多少(画的跟屎一样 😂)
----
| |
----
| |
----
有点类似我们数字时钟那个样子,如下
要求就是亮的部分不能断层,比如下面这些
---- ---- ---- ----
| | |
---- ----
| |
----
(可以) (可以) (可以) (不可以)
这题做不出来 😂,太菜了,最后数了数亮 1 个到亮全部的个数,就提交了…
排序次数 🔗
说的是冒泡排序,求一个交换次数为100
的最短且字典序拍最前的字符串
比如bnl
需要交换1
次(n
和l
互换)
我的想法就是,比如dcba
这种全倒排需要的次数是最大的,这个交换的次数就是
3([d,c]->[d,b]->[d,a])+2([c,b]->[c,a])+1([b,a]) = 6
所以可以知道要超过100
次,那么此时最短的字符串应为onmlkjihgfedcba
这时的比较次数为14+13+...+1=105
,如果是长度13
,那么结果只有91
,不符合题意
但此时感觉不是字典序最短的,当时想着把onmlkjihgfedcba
最前面的两个变成有序地来分析
nomlkjihgfedcba
,n
和o
交换,影响o
的的交换次数,而不影响n
的交换次数
onmlkjihgfedcba
在o
冒泡到最末尾时,为nmlkjihgfedcbao
,此时交换14
次nomlkjihgfedcba
在o
冒泡到最末尾时,为nmlkjihgfedcbao
,此时交换13
次
字典序nomlkjihgfedcba
是小于onmlkjihgfedcba
的,所以还有优化的空间,
也就是前面多少个字符顺序了会最接近次数100
又试了下前面3
个顺序时,mnolkjihgfedcba
,
- 对于
o
,少比较2
次 - 对于
n
,少比较1
次
那么就少了3
次,还是符合,但是如果前面4
个有序,此时少了3+2+1=6
次,就不符合了
综上,我的答案为mnolkjihgfedcba
,一通分析感觉相当有道理(还是有点小慌 🤣)
成绩分析 🔗
这题是不是有圈套,有点太基础的感觉…
给 n 个分数,0-100
,计算最大值,最小值和平均值
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int max = -1;
int min = 101;
int sum = 0;
for (int i = 1; i <= n; i++) {
int cur = in.nextInt();
max = Math.max(max, cur);
min = Math.min(min, cur);
sum += cur;
}
System.out.println(max);
System.out.println(min);
// 保留2位小数
System.out.println(Math.round(sum * 1.0 / n * 100) * 1.0 / 100);
}
}
单词分析 🔗
emmm,这题是不是也有圈套???
给定一个字符串,计算出现次数最多的字符和它的次数
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
int[] map = new int[26];
for (int i = 0; i < s.length(); i++) {
map[s.charAt(i) - 'a']++;
}
char maxC = ' ';
int count = 0;
for (int i = 0; i < map.length; i++) {
if (map[i] > count) {
count = map[i];
maxC = (char) (i + 'a');
}
}
System.out.println(maxC);
System.out.println(count);
}
}
数字三角形 🔗
这题和之前那个金字塔数字求和很像
从上往下找累加最大值,比如
10
10 1
10 2 3
10 3 4 5
上面最大值为40
,但是这题还有一个限制,就是往左和往右的次数之差不能超过1
import java.util.Scanner;
public class Main {
static int max = 0;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[][] array = new int[n][n];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j <= i; j++) {
array[i][j] = in.nextInt();
}
}
max = 0;
dfs(array, 0, 0, 0, 0, 0);
System.out.println(max);
}
static void dfs(int[][] array, int n, int j, int left, int right, int curSum) {
// 剪枝
if (left > array.length / 2 || right > array.length / 2) {
return;
}
if (n == array.length - 1) {
max = Math.max(max, curSum + array[n][j]);
System.out.println(left + "-" + right);
return;
}
dfs(array, n + 1, j, left + 1, right, curSum + array[n][j]);
dfs(array, n + 1, j + 1, left, right + 1, curSum + array[n][j]);
}
}
字串分值和 🔗
这题 emmm,用了不知道叫不叫方法的方法
给定一个字符串(只包含小写字母),计算它所有字串的分值的和
分值的计算,比如对于ababc
分值就是该字符串不重复字符的个数,对于上面这个,也就是3
我的想法就是双重遍历,记忆前一个字串的分值,然后累加。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine().trim();
int[] map = new int[26];
int sum = 0;
for (int i = 0; i < s.length(); i++) {
Arrays.fill(map, 0);
int curSum = 0;
for (int j = i; j < s.length(); j++) {
int index = s.charAt(j) - 'a';
if (map[index] == 0) {
map[index]++;
curSum++;
}
sum += curSum;
}
}
System.out.println(sum);
}
}
装饰珠 🔗
这个真没看懂,题目都没读懂,回来基本上就忘了
给定6
件装备,每件装备有n
个镶嵌孔,镶嵌孔有等级,可以镶嵌不大于这个等级的镶嵌珠
镶嵌镶嵌珠可以产生价值,相同的镶嵌珠可以增加价值
给定 m 种镶嵌珠,给定镶嵌 k 个第 i 种镶嵌珠产生的价值,
求6
件装备产生的最大价值
不会…