2020蓝桥杯模拟赛题解(Java语言描述)

T1

问题描述
  1200000有多少个约数(只计算正约数)。
答案提交
  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

分析:
填空题+小数据,暴力求解即可:

public class Test1 {
    public static void main(String[] args) {
        int counter = 0;
        for (int i = 1; i <= 1200000; i++) {
            if (1200000 % i == 0) {
                counter++;
            }
        }
        System.out.println(counter);
    }
}

答案:96

T2

问题描述
  在计算机存储中,15.125GB是多少MB?
答案提交
  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

分析:
1GB=1024MB。

答案:15488

T3

问题描述
  一棵包含有2019个结点的二叉树,最多包含多少个叶结点?
答案提交
  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

分析:
这题挺坑的,很多人可能按照二叉树做,发挥了其强大的离散数学or数据结构基础知识,但错了。
其实就可以是一个单根+2018叶子结点的2018叉树。

答案:2018

T4

问题描述
  在1至2019中,有多少个数的数位中包含数字9?
  注意,有的数中的数位中包含多个9,这个数只算一次。例如,1999这个数包含数字9,在计算只是算一个数。
答案提交
  这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

分析:
这题本该是有讲究的,可惜数据量小还是填空题,就可以开暴力:

public class Main {
    public static void main(String[] args) {
        int counter = 0;
        for (int i = 1; i <= 2019; i++) {
            if (Integer.toString(i).contains("9")) {
                counter++;
            }
        }
        System.out.println(counter);
    }
}

答案:544

T5

问题描述
  一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,例如1135是一个数位递增的数,而1024不是一个数位递增的数。
  给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数?
输入格式
  输入的第一行包含一个整数 n。
输出格式
  输出一行包含一个整数,表示答案。
样例输入
30
样例输出
26
评测用例规模与约定
  对于 40% 的评测用例,1 <= n <= 1000。
  对于 80% 的评测用例,1 <= n <= 100000。
  对于所有评测用例,1 <= n <= 1000000。

分析:
  开暴力求解,利用char[]来逐一比较。

答案:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt(), counter = 0;
        scanner.close();
        char[] temp;
        char prev;
        outer:
        for (int i = 1; i <= num; i++) {
            temp = Integer.toString(i).toCharArray();
            prev = temp[0];
            for (int j = 1; j < temp.length; j++) {
                if (prev > temp[j]) {
                    continue outer;
                }
                prev = temp[j];
            }
            counter++;
        }
        System.out.println(counter);
    }
}

T6

问题描述
  小明对类似于 hello 这种单词非常感兴趣,这种单词可以正好分为四段,第一段由一个或多个辅音字母组成,第二段由一个或多个元音字母组成,第三段由一个或多个辅音字母组成,第四段由一个或多个元音字母组成。
  给定一个单词,请判断这个单词是否也是这种单词,如果是请输出yes,否则请输出no。
  元音字母包括 a, e, i, o, u,共五个,其他均为辅音字母。
输入格式
  输入一行,包含一个单词,单词中只包含小写英文字母。
输出格式
  输出答案,或者为yes,或者为no。
样例输入
lanqiao
样例输出
yes
样例输入
world
样例输出
no
评测用例规模与约定
  对于所有评测用例,单词中的字母个数不超过100。

分析:
  使用正则表达式即可,matches()是since1.4的,就能用。
注意这个正则怎么写的,我们把元音字母1+和辅音字母1+分别做成正则表达式的子表达式,最后使用字符串连接凑成完整的正则表达式。
[ a e i o u ] + [aeiou]+ 表示任意 a、e、i、o、u 元素连续出现一次以上的贪婪匹配,
[ b c d f g h j k l m n p q r s t v w x y z ] + [bcdfghjklmnpqrstvwxyz]+ 表示辅音字母元素连续出现一次以上的贪婪匹配。
  由于是贪婪匹配,所以能尽可能多的匹配,而不会导致意外的Bug。

答案:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        String regex1 = "[aeiou]+", regex2 = "[bcdfghjklmnpqrstvwxyz]+";
        Scanner scanner = new Scanner(System.in);
        System.out.println((scanner.nextLine().matches(regex2+regex1+regex2+regex1)) ? "yes" : "no");
        scanner.close();
    }
}

T7

问题描述
  在数列 a[1], a[2], …, a[n] 中,如果对于下标 i, j, k 满足 0<i<j<k<n+1 且 a[i]<a[j]<a[k],则称 a[i], a[j], a[k] 为一组递增三元组,a[j]为递增三元组的中心。
  给定一个数列,请问数列中有多少个元素可能是递增三元组的中心。
输入格式
  输入的第一行包含一个整数 n。
  第二行包含 n 个整数 a[1], a[2], …, a[n],相邻的整数间用空格分隔,表示给定的数列。
输出格式
  输出一行包含一个整数,表示答案。
样例输入
5
1 2 5 3 5
样例输出
2
样例说明
  a[2] 和 a[4] 可能是三元组的中心。
评测用例规模与约定
  对于 50% 的评测用例,2 <= n <= 100,0 <= 数列中的数 <= 1000。
  对于所有评测用例,2 <= n <= 1000,0 <= 数列中的数 <= 10000。

分析:
  开三指针即可,一个从1开始移动,剩下两个就在两侧移动,只要找到一组符合要求的就可以counter++。

答案:

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int num = Integer.parseInt(reader.readLine()), counter = 0;
        String[] nums = reader.readLine().split("\\s+");
        reader.close();
        int[] array = new int[num];
        for (int i = 0; i < num; i++) {
            array[i] = Integer.parseInt(nums[i]);
        }
        outer:
        for (int j = 1; j < num; j++) {
            for (int i = 0; i < j; i++) {
                for (int k = j+1; k < num; k++) {
                    if (array[i] < array[j] && array[j] < array[k]) {
                        counter++;
                        continue outer;
                    }
                }
            }
        }
        System.out.println(counter);
    }
}

T8

问题描述
  小明有一块空地,他将这块空地划分为 n 行 m 列的小块,每行和每列的长度都为 1。
  小明选了其中的一些小块空地,种上了草,其他小块仍然保持是空地。
  这些草长得很快,每个月,草都会向外长出一些,如果一个小块种了草,则它将向自己的上、下、左、右四小块空地扩展,这四小块空地都将变为有草的小块。
  请告诉小明,k 个月后空地上哪些地方有草。
输入格式
  输入的第一行包含两个整数 n, m。
  接下来 n 行,每行包含 m 个字母,表示初始的空地状态,字母之间没有空格。如果为小数点,表示为空地,如果字母为 g,表示种了草。
  接下来包含一个整数 k。
输出格式
  输出 n 行,每行包含 m 个字母,表示 k 个月后空地的状态。如果为小数点,表示为空地,如果字母为 g,表示长了草。
样例输入
4 5
.g…

…g…

2
样例输出
gggg.
gggg.
ggggg
.ggg.
评测用例规模与约定
  对于 30% 的评测用例,2 <= n, m <= 20。
  对于 70% 的评测用例,2 <= n, m <= 100。
  对于所有评测用例,2 <= n, m <= 1000,1 <= k <= 1000。

分析:
  开一个BFS,注意判断防止重复搜索。
搜的时候,使用双队列,一个装x一个装y,每一轮都让原队列元素出队,周围能种草的位置入队。
  循环k轮,效率不至于太差。
  注意判越界。

答案:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
    public static void main(String[] args) throws IOException {
        //sb Java6
        Queue<Integer> queue_x = new LinkedList<Integer>();
        Queue<Integer> queue_y = new LinkedList<Integer>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] line1 = reader.readLine().split("\\s+");
        int n = Integer.parseInt(line1[0]), m = Integer.parseInt(line1[1]);
        char[][] graph = new char[n][m];
        for (int i = 0; i < n; i++) {
            char[] temp = reader.readLine().toCharArray();
            for (int j = 0; j < m; j++) {
                graph[i][j] = temp[j];
                if (temp[j] == 'g') {
                    queue_x.offer(i);
                    queue_y.offer(j);
                }
            }
        }
        int k = Integer.parseInt(reader.readLine());
        reader.close();
        for (int i = 0; i < k; i++) {
            int length = queue_x.size();
            for (int j = 0; j < length; j++) {
                int x = queue_x.poll(), y = queue_y.poll();
                if (x != 0 && graph[x-1][y] == '.') {
                    queue_x.offer(x-1);
                    queue_y.offer(y);
                    graph[x-1][y] = 'g';
                }
                if (x != n-1 && graph[x+1][y] == '.') {
                    queue_x.offer(x+1);
                    queue_y.offer(y);
                    graph[x+1][y] = 'g';
                }
                if (y != 0 && graph[x][y-1] == '.') {
                    queue_x.offer(x);
                    queue_y.offer(y-1);
                    graph[x][y-1] = 'g';
                }
                if (y != m-1 && graph[x][y+1] == '.') {
                    queue_x.offer(x);
                    queue_y.offer(y+1);
                    graph[x][y+1] = 'g';
                }
            }
        }
        StringBuilder result;
        for (int i = 0; i < n; i++) {
            result = new StringBuilder();
            for (int j = 0; j < m; j++) {
                result.append(graph[i][j]);
            }
            System.out.println(result);
        }
    }
}

T9

问题描述
  小明想知道,满足以下条件的正整数序列的数量:
  1. 第一项为 n;
  2. 第二项不超过 n;
  3. 从第三项开始,每一项小于前两项的差的绝对值。
  请计算,对于给定的 n,有多少种满足条件的序列。
输入格式
  输入一行包含一个整数 n。
输出格式
  输出一个整数,表示答案。答案可能很大,请输出答案除以10000的余数。
样例输入
4
样例输出
7
样例说明
  以下是满足条件的序列:
  4 1
  4 1 1
  4 1 2
  4 2
  4 2 1
  4 3
  4 4
评测用例规模与约定
  对于 20% 的评测用例,1 <= n <= 5;
  对于 50% 的评测用例,1 <= n <= 10;
  对于 80% 的评测用例,1 <= n <= 100;
  对于所有评测用例,1 <= n <= 1000。

分析:
  使用动态规划求解,动态转移方程: f [ i ] [ j ] = f [ j ] [ 1 ] + + f [ j ] [ a b s ( i j ) 1 ] + 1 f[i][j] = f[j][1] + … + f[j][abs(i-j)-1] + 1

答案:

import java.util.Scanner;

public class Main {

    private static int[][] array;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        scanner.close();
        array = new int[num+1][num+1];
        int counter = 0;
        for (int i = 1; i <= num; i++) {
            counter += count(num, i);
        }
        System.out.println(counter % 10000);
    }

    private static int count(int n, int m) {
        if (array[n][m] != 0) {
            return array[n][m];
        }
        int temp = 1;
        for (int j = 1; j < Math.abs(n - m); j++) {
            temp = (temp + count(m, j)) % 10000;
        }
        return array[n][m] = temp;
    }

}

T10

问题描述
  小明要组织一台晚会,总共准备了 n 个节目。然后晚会的时间有限,他只能最终选择其中的 m 个节目。
  这 n 个节目是按照小明设想的顺序给定的,顺序不能改变。
  小明发现,观众对于晚上的喜欢程度与前几个节目的好看程度有非常大的关系,他希望选出的第一个节目尽可能好看,在此前提下希望第二个节目尽可能好看,依次类推。
  小明给每个节目定义了一个好看值,请你帮助小明选择出 m 个节目,满足他的要求。
输入格式
  输入的第一行包含两个整数 n, m ,表示节目的数量和要选择的数量。
  第二行包含 n 个整数,依次为每个节目的好看值。
输出格式
  输出一行包含 m 个整数,为选出的节目的好看值。
样例输入
5 3
3 1 2 5 4
样例输出
3 5 4
样例说明
  选择了第1, 4, 5个节目。
评测用例规模与约定
  对于 30% 的评测用例,1 <= n <= 20;
  对于 60% 的评测用例,1 <= n <= 100;
  对于所有评测用例,1 <= n <= 100000,0 <= 节目的好看值 <= 100000。

答案:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] line1 = reader.readLine().split("\\s+");
        int n = Integer.parseInt(line1[0]), m = Integer.parseInt(line1[1]);
        String[] line2 = reader.readLine().split("\\s+");
        reader.close();
        int[] likes = new int[n], sorted_likes = new int[n];
        for (int i = 0; i < n; i++) {
            sorted_likes[i] = likes[i] = Integer.parseInt(line2[i]);
        }
        Arrays.sort(sorted_likes);
        List<Integer> list = new ArrayList<Integer>();
        for (int i = n - m; i < n; i++) {
            list.add(sorted_likes[i]);
        }
        StringBuilder result = new StringBuilder();
        for (int i : likes) {
            if (list.contains(i)) {
                list.remove(Integer.valueOf(i));
                result.append(i).append(' ');
            }
        }
        System.out.println(result.toString().trim());
    }
}

总作答时间

2h以内……

发布了734 篇原创文章 · 获赞 1573 · 访问量 73万+

猜你喜欢

转载自blog.csdn.net/weixin_43896318/article/details/105010841