蓝桥杯2019JAVA_B省赛真题详解

第一题:组队

题目描述

作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容。

每位球员担任 1 号位至 5 号位时的评分如下表所示。请你计算首发阵容 1 号位至 5 号位的评分之和最大可能是多少?

(如果你把以上文字复制到文本文件中,请务必检查复制的内容是否与文 档中的一致。在试题目录下有一个文件 team.txt,内容与上面表格中的相同, 请注意第一列是编号)

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

解题思路

Excel
答案:490


第二题:不同子串

题目描述

一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成 的串。例如,字符串aaab 有非空子串a, b, aa, ab, aaa, aab, aaab,一共 7 个。 注意在计算时,只算本质不同的串的个数。

请问,字符串0100110001010001 有多少个不同的非空子串?

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

解题思路

两个节点 begin end 开始 双循环走动

import java.util.ArrayList;
public class demo02不同字串 {
public static void main(String[] args) {
    String s = "0100110001010001";
    ArrayList<String> ku = new ArrayList<>();
    for (int begin = 0; begin < 16; begin++) {
        for (int end = begin; end <16 ; end++) {
            String s1 = s.substring(begin,end+1);
            if(!ku.contains(s1))
                ku.add(s1);
        }
    }

    System.out.println(ku);
    System.out.println(ku.size());  //100
}
    
}


第三题:数列求值

题目描述

给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和。求 第 20190324 项的最后 4 位数字。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个 4 位整数(提示:答案的千位不为 0),在提交答案时只填写这个整数,填写 多余的内容将无法得分。

解题思路

数列的性质
在一个有规律的数列中
整体对一个数取余 和 取余之后按原本规律进行 是一样的
描述不清 看代码吧 这是数学规律

/**
 * @author sjf
 * @date 2020/3/20 22:13
 */

public class demo03数列求值 {
    public static void main(String[] args) {

        int a1 = 1;
        int a2 = 1;
        int a3 = 1;
        int ans = 0;

        for (int i = 4; i <=  20190324 ; i++) {
            ans = (a1 + a2 + a3)%10000;  //求一个数的后四位 对 10000 取余
            a1 = a2;
            a2 = a3;
            a3 = ans;
        }

        System.out.println(ans);  //4659
    }
}


第四题:数的分解

题目描述

把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包 含数字 2 和 4,一共有多少种不同的分解方法?

注意交换 3 个整数的顺序被视为同一种方法,例如 1000+1001+18 和 1001+1000+18 被视为同一种。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

解题思路

枚举 注意优化
这种大小排好序的优化
既节省时间 又去重

枚举假设获得 3 个数 i,j,k ,保证 i<j<k。
i 从 1 开始枚举,到 673 结束,因为 i 是最小的,
所以必须小于 2019 的 1/3.j 从 i+1 开始枚举,到 (2019-i)/2 结束。
这是因为这样的话可以保证 i<j<k。k 不用枚举,直接就是 2019-i-j 计算得到。
其实每次枚举出 i 和 j 时,可以先判断这个数是否符合数字的要求。
如果不符合,就不用继续枚举下一个数字,而是枚举这个数字的下一个。
当然这个程序里面没有加上这个优化,因为写起来有点麻烦,
这个程序已经效率够高了。

/**
 * @author sjf
 * @date 2020/3/20 22:20
 */


public class demo04数的分解 {
    public static void main(String[] args) {

        int count = 0;
        //两重枚举 i<j<k 这样既优化枚举 也可以 去重
        //优化枚举后 这个边界很难掌控 要细心!!
        for (int i = 1; i <=2019/3 ; i++) {
            if(check(i))
            for (int j = i+1 ; j <=(2019-i)/2 ; j++) {
                int k = 0;
                if(check(j)) {
                     k = 2019 - i - j;
                    if(k!=i&&k!=j&&check(k)) {
                        count++;
                        System.out.println(" "+i+" "+j+" "+k);
                    }
                }

            }

        }

        System.out.println(count);  //40785
    }

    /**
     * 检查是否含有 2 和 4
     * @param n
     * @return
     */
    public static boolean check(int n ){

        while (n!=0){
            int yu = n%10;
            n/=10;
            if(yu == 2 || yu == 4)
                return false;
        }

        return true;


    }
}


第五题:迷宫

题目描述

下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方。
010000 000100 001001 110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左、右四个方向之一。

对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫, 一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。

对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。 请注意在字典序中D<L<R<U。(如果你把以下文字复制到文本文件中,请务 必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 maze.txt, 内容与下面的文本相同)
在这里插入图片描述
文本数据 在代码中 自行 ctrl c v

【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个字符串,包含四种字母 D、U、L、R,在提交答案时只填写这个字符串,填 写多余的内容将无法得分。

解题思路

经典搜索题了
给出一个dfs的解题思路 bfs随后再说
这个题用dfs 可能会用很长的时间


利用bfs 需要学习一下队列
这道题考的基本还是bfs框架
需要一下进行路径记忆 只需在节点中添加一个f来储存此时head在que数组中的下标
最后逆向追踪 即可找到路径


import java.util.Scanner;

/**
 * @author sjf
 * @date 2020/3/23 11:38
 */

class note{

    int x ;
    int y;
    int step;
    int f;  //记录路径 每一步在que数组中的下标

    public note(int x, int y, int step, int f) {
        this.x = x;
        this.y = y;
        this.step = step;
        this.f =  f;
    }

    @Override
    public String toString() {
        return "note{" +
                "x=" + x +
                ", y=" + y +
                ", step=" + step +
                ", f=" + f +
                '}';
    }
}


public class bfs {

    static char[][] map = new char[30][50];
    static int[][] book = new int [30][50];
    static int[][] next = {{0,1}/*右*/,{1,0}/*下*/,{0,-1}/*左*/,{-1,0}/*上*/};

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        for (int i = 0; i <map.length ; i++) {
            String s = sc.next();
            map[i] = s.toCharArray();
        }

        note[] que = new note[1501]; //地图面积大小
        int head=0,tail=0;
        que[tail] = new note(0,0,0,-1);
        //创建队列  头结点和身体结点都在 0
        tail++;  //自然 身体结点往后移
        book[0][0] = 1;

        int flag = 0; //标记是否到达目的地
        int tx=0,ty=0;
        while (head < tail){

            //枚举四个方向

            for (int i = 0; i < 4 ; i++) {
                 tx = que[head].x + next[i][0];
                 ty = que[head].y + next[i][1];

            //判断是否越界
            if(tx<0||tx>=30||ty<0||ty>=50)
                continue;
            //判断是否是障碍物或者在路径中
            if (map[tx][ty]=='0' && book[tx][ty]==0 ){
                //把这个点标记为走过
                book[tx][ty] = 1;
                //添加到队列中
                que[tail] = new note(tx,ty,que[head].step+1,head);
                tail++;
            }
            //如果到目标点了,停止扩展,任务结束,退出循环
            if (tx == 29 &&ty == 49){
                flag =1;
                break;
            }
            }
            if(flag == 1 )
                break;

            head++;  //当一个点拓展结束之后,移到下一个结点,对之后的点进行拓展

        }

        System.out.println(que[tail-1].step);
//        for (int i = 0; i <tail ; i++) {
//            System.out.println(que[i].f);
//        }

        StringBuffer swap =new StringBuffer();
        for (int i = tail-1 ; que[i].f >=0 ; ) {
            for (int j = 0; j < 4 ; j++) {
                if(que[que[i].f].x+next[j][0] == que[i].x &&
                   que[que[i].f].y+next[j][1] == que[i].y ){

                    if(j==0)
                        swap.append("R");
                    if(j==1)
                        swap.append("D");
                    if(j==2)
                        swap.append("L");
                    if(j==3)
                        swap.append("U");
                }
            }
            i = que[i].f;
        }
        System.out.println(swap.reverse());
    }
}


/*
01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000
*/

答案:
DDDDRRURRRRRRRDRRRDDDLDDRDDDDDDDDDDDDRDRDRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDRDRRRRDRDRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR


第六题:特别数的和

题目描述

小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。

请问,在 1 到 n 中,所有这样的数的和是多少?

【输入格式】

输入一行包含两个整数 n。

【输出格式】

输出一行,包含一个整数,表示满足条件的数的和。

【样例输入】

40

【样例输出】

574

【评测用例规模与约定】

对于 20% 的评测用例,1≤n≤10。

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

对于 80% 的评测用例,1≤n≤1000。

对于所有评测用例,1≤n≤10000。

时间限制:1.0s

内存限制:512.0MB

解题思路

水了

import java.util.Scanner;

/**
 * @author sjf
 * @date 2020/3/8 10:51
 */


public class demo06特别数的和 {
    public static void main(String[] args) {


        long sum  = 0;
        int n = new Scanner(System.in).nextInt();
        for (int i = 1; i <= n; i++) {

            if(f(i))
               sum+=i;
        }

        System.out.println(sum);
    }


    /**
     * 判断一个位数上是否有2 0 1 9
     * @param n
     * @return
     */
    public static boolean f( int  n ){
        while(n!=0){
            int t = n%10;
            if(t==2||t==0||t==1||t==9){
                return true;
            }
            n/=10;
        }
        return false;
    }


}


第七题:外卖店优先级

题目描述

“饱了么”外卖系统中维护着 N 家外卖店,编号 1 ∼ N。每家外卖店都有 一个优先级,初始时 (0 时刻) 优先级都为 0。

每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减 到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。

如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果 优先级小于等于 3,则会被清除出优先缓存。

给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优 先缓存中。

【输入格式】

第一行包含 3 个整数 N、M 和 T。

以下 M 行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id 的外卖店收到 一个订单。

【输出格式】

输出一个整数代表答案。

【样例输入】

2 6 6
1 1
5 2
3 1
6 2
2 1
6 2

【样例输出】

1

【样例解释】

6 时刻时,1 号店优先级降到 3,被移除出优先缓存;2 号店优先级升到 6, 加入优先缓存。所以是有 1 家店 (2 号) 在优先缓存中。

【评测用例规模与约定】

对于 80% 的评测用例,1≤ N,M,T ≤10000。
对于所有评测用例,1≤ N,M,T ≤100000,1≤ts≤T,1≤id ≤ N。

时间限制:1.0s

内存限制:512.0MB

解题思路

利用结构体 就很简单了
遍历一遍 模拟题
代码里有几个测试样例 可以自己写写测测


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

/**
 * @author sjf
 * @date 2020/3/21 9:51
 */

class log{

    int ts;
    int id;

    public log(int ts, int id) {
        this.ts = ts;
        this.id = id;
    }

    @Override
    public String toString() {
        return "\nlog{" +
                "ts=" + ts +
                ", id=" + id +
                '}';
    }
}

public class demo07外卖店优先级 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int N,M,T;
        N = sc.nextInt();
        M = sc.nextInt();
        T = sc.nextInt();

        ArrayList<log> log1 = new ArrayList<>();
        for (int i = 0; i < M; i++) {
            int tst = sc.nextInt();
            int idt = sc.nextInt();

            log1.add(new log(tst,idt));

        }

        Collections.sort(log1, new Comparator<log>() {
            @Override
            public int compare(log o1, log o2) {
                int result = o1.id - o2.id;
                if(result == 0 )
                    result = o1.ts - o2.ts;
                return result;
            }
        });

        log1.add(new log(0,0));

        //System.out.println(log1);
        int count = 0;
        int ans = 0;
        int previousid = 0;
        int flag= 0; //用来标记 是否在优先缓冲区中
        for (int i = 0; i < M ; i++) {
            //新的店铺
            if(log1.get(i).id != previousid ){
                count=2;  //首先加一个 2
                previousid = log1.get(i).id;
                flag =0;
            }
            else if(log1.get(i).ts != log1.get(i-1).ts) {
                count += (log1.get(i - 1).ts + 1 - log1.get(i).ts);
                if (count<=3)
                    flag = 0;
                //这种情况不能忽视
                if (count < 0)
                    count = 2;
                else
                    count+=2;
            }
            else
                count += 2;

            if (count<=3)
                flag = 0;
              if (count>5)
                flag = 1;
            //店铺的最后一个订单
            if( log1.get(i).id != log1.get(i+1).id){
                count -= (T - log1.get(i).ts);

                if(count > 3 && flag == 1)
                    ans++;
            }

        }
        System.out.println(ans);
    }
}
/*
3 8 6
1 1
2 1
6 2
5 3
6 3
5 3
5 1
6 1

2 5 3
1 1
1 1
1 1
2 2
1 2

1 5 100
1 1
2 1
98 1
99 1
100 1


 */

第八题:人物相关性分析

题目描述

小明正在分析一本小说中的人物相关性。他想知道在小说中 Alice 和 Bob 有多少次同时出现。

更准确的说,小明定义 Alice 和 Bob“同时出现”的意思是:在小说文本 中 Alice 和 Bob 之间不超过 K 个字符。

例如以下文本:

ThisisastoryaboutAliceandBob.AlicewantstosendaprivatemessagetoBob.

假设 K = 20,则 Alice 和 Bob 同时出现了 2 次,分别是”Alice and Bob” 和”Bob. Alice”。前者 Alice 和 Bob 之间有 5 个字符,后者有 2 个字符。

注意:

  1. Alice 和 Bob 是大小写敏感的,alice 或 bob 等并不计算在内。
  2. Alice 和 Bob 应为单独的单词,前后可以有标点符号和空格,但是不能 有字母。例如 Bobbi 並不算出现了 Bob。

【输入格式】

第一行包含一个整数 K。
第二行包含一行字符串,只包含大小写字母、标点符号和空格。长度不超 过 1000000。

【输出格式】

输出一个整数,表示 Alice 和 Bob 同时出现的次数。

【样例输入】

20
ThisisastoryaboutAliceandBob.AlicewantstosendaprivatemessagetoBob.

【样例输出】

2

【评测用例规模与约定】

对于所有评测用例,1≤ K ≤1000000。

时间限制:1.0s

内存限制:512.0MB
题解待更新


第九题:后缀表达式

题目描述

给定 N 个加号、M 个减号以及 N + M + 1 个整数 A1,A2,··· ,AN+M+1,小 明想知道在所有由这 N 个加号、M 个减号以及 N + M +1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个?

请你输出这个最大的结果。

例如使用1 2 3 + -,则 “2 3 + 1 -” 这个后缀表达式结果是 4,是最大的。

【输入格式】

第一行包含两个整数 N 和 M。 第二行包含 N + M + 1 个整数 A1,A2,··· ,AN+M+1。

【输出格式】

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

【样例输入】

1 1
1 2 3

【样例输出】

4

【评测用例规模与约定】

对于所有评测用例,0≤ N,M ≤100000,−109 ≤ Ai ≤109。

时间限制:1.0s

内存限制:512.0MB
题解待更新


第十题:灵能传输

题目描述

【题目背景】

在游戏《星际争霸 II》中,高阶圣堂武士作为星灵的重要 AOE 单位,在 游戏的中后期发挥着重要的作用,其技能”灵能风暴“可以消耗大量的灵能对 一片区域内的敌军造成毁灭性的伤害。经常用于对抗人类的生化部队和虫族的 刺蛇飞龙等低血量单位。

【问题描述】

你控制着 n 名高阶圣堂武士,方便起见标为 1,2,··· ,n。每名高阶圣堂武士 需要一定的灵能来战斗,每个人有一个灵能值 ai 表示其拥有的灵能的多少(ai 非负表示这名高阶圣堂武士比在最佳状态下多余了 ai 点灵能,ai 为负则表示这 名高阶圣堂武士还需要 −ai 点灵能才能到达最佳战斗状态)。现在系统赋予了 你的高阶圣堂武士一个能力,传递灵能,每次你可以选择一个 i ∈ [2,n−1],若 ai ≥ 0 则其两旁的高阶圣堂武士,也就是 i−1、i + 1 这两名高阶圣堂武士会从 i 这名高阶圣堂武士这里各抽取 ai 点灵能;若 ai < 0 则其两旁的高阶圣堂武士, 也就是 i−1,i+1 这两名高阶圣堂武士会给 i 这名高阶圣堂武士 −ai 点灵能。形 式化来讲就是 ai−1+ = ai,ai+1+ = ai,ai−= 2ai。

灵能是非常高效的作战工具,同时也非常危险且不稳定,一位高阶圣堂 武士拥有的灵能过多或者过少都不好,定义一组高阶圣堂武士的不稳定度为 maxn i=1|ai|,请你通过不限次数的传递灵能操作使得你控制的这一组高阶圣堂武 士的不稳定度最小。

【输入格式】

本题包含多组询问。输入的第一行包含一个正整数 T 表示询问组数。 接下来依次输入每一组询问。 每组询问的第一行包含一个正整数 n,表示高阶圣堂武士的数量。 接下来一行包含 n 个数 a1,a2,··· ,an。

【输出格式】

输出 T 行。每行一个整数依次表示每组询问的答案。

【样例输入】

3
3
5 -2 3
4
0 0 0 0
3
1 2 3
【样例输出】

3
0
3

【样例说明】

对于第一组询问:
对 2 号高阶圣堂武士进行传输操作后 a1 = 3,a2 = 2,a3 = 1。答案为 3。

对于第二组询问:
这一组高阶圣堂武士拥有的灵能都正好可以让他们达到最佳战斗状态。

【样例输入】
3
4
-1 -2 -3 7
4
2 3 4 -8
5
-1 -1 6 -1 -1

【样例输出】

5
7
4

【样例输入】

见文件trans3.in。

【样例输出】

见文件trans3.ans。

【数据规模与约定】

对于所有评测用例,T ≤3,3≤n≤300000,|ai|≤109。
评测时将使用 25 个评测用例测试你的程序,每个评测用例的限制如下:
在这里插入图片描述
注意:本题输入量较大请使用快速的读入方式。

时间限制:5.0s

内存限制:512.0MB
题解待更新

发布了16 篇原创文章 · 获赞 94 · 访问量 4493

猜你喜欢

转载自blog.csdn.net/qq_45756224/article/details/105017261