第十四届蓝桥杯模拟赛第一期试题与题解Java

在这里插入图片描述



A 二进制位数

问题描述

十进制整数 2 在十进制中是 1 位数,在二进制中对应 10 ,是 2 位数。
十进制整数 22 在十进制中是 2 位数,在二进制中对应 10110 ,是 5 位数。
请问十进制整数 2022 在二进制中是几位数?

答案提交

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

参考答案

11

个人题解

方法一: 直接使用Java提供的API将2022转成二进制数表示的字符串,求出字符串长度即可:

public class Main {
    
    

    public static void main(String[] args) {
    
    
        int number = 2022;
        System.out.println(Integer.toBinaryString(number).length());
    }
}

方法二: 使用位运算去模拟:

public class Main {
    
    

    public static void main(String[] args) {
    
    
        int number = 2022;
        int count = 0;//记录位数
        while (number > 0){
    
    
            ++count;
            number >>= 1;
        }
        System.out.println(count);
    }
}

B 晨跑

问题描述

小蓝每周六、周日都晨跑,每月的 1、11、21、31日也晨跑。其它时间不晨跑。
已知 2022年1月1日是周六,请问小蓝整个2022年晨跑多少天?

答案提交

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

个人题解

138

public class Main {
    
    

    public static void main(String[] args) {
    
    
        //days[1] = 31表示1月有31天
        int[] days = {
    
    0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int count = 0; //用于记录符合条件的天数
        int today = 6; //表示星期6, 0表示星期天
        //枚举筛选
        for (int i = 1; i <= 12; i++) {
    
    
            for (int j = 1; j <= days[i]; j++) {
    
    
                if (today == 6 || today == 0 || j == 1 || j == 11 || j == 21 || j == 31){
    
    
                    ++count;
                }
                today = (today + 1) % 7;
            }
        }
        //打印结果
        System.out.println(count);
    }
}

C 调和级数

问题描述

小蓝特别喜欢调和级数 S(n)=1/1+1/2+1/3+1/4+…+1/n 。
请问,n 至少为多大时,S(n)>12 ?

答案提交

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

个人题解

91380

public class Main {
    
    

    public static void main(String[] args) {
    
    
        int n = 2;
        int calculate = calculate(2, 12);
        System.out.println(calculate); //91380
    }

    public static int calculate(int n, int border){
    
    
        double res = 1.0;
        while (true){
    
    
            res += 1.0 / n;
            if (res > border){
    
    
                return n;
            }
            System.out.println(n + ", res = " + res); //打印中间结果,避免死循环
            ++n;
        }
    }
}

D 山谷

问题描述

给定一个字母矩阵,如果矩阵中的某个位置不在四条边上,而且该位置上的字母小于其上下左右四个位置的字母,则称为一个山谷。
例如,对于如下矩阵

DDDDD
CADCE
FFFFA

共有两个山谷,位于第二行第二列和第四列。请注意第二行第三列和第三行第五列都不是山谷。
对于如下30行60列的字母矩阵(请用等宽字体查看),请问有多少个山谷?

PHQGHUMEAYLNLFDXFIRCVSCXGGBWKFNQDUXWFNFOZVSRTKJPREPGGXRPNRVY
STMWCYSYYCQPEVIKEFFMZNIMKKASVWSRENZKYCXFXTLSGYPSFADPOOEFXZBC
OEJUVPVABOYGPOEYLFPBNPLJVRVIPYAMYEHWQNQRQPMXUJJLOOVAOWUXWHMS
NCBXCOKSFZKVATXDKNLYJYHFIXJSWNKKUFNUXXZRZBMNMGQOOKETLYHNKOAU
GZQRCDDIUTEIOJWAYYZPVSCMPSAJLFVGUBFAAOVLZYLNTRKDCPWSRTESJWHD
IZCOBZCNFWLQIJTVDWVXHRCBLDVGYLWGBUSBMBORXTLHCSMPXOHGMGNKEUFD
XOTOGBGXPEYANFETCUKEPZSHKLJUGGGEKJDQZJENPEVQGXIEPJSRDZJAZUJL
LCHHBFQMKIMWZOBIWYBXDUUNFSKSRSRTEKMQDCYZJEEUHMSRQCOZIJIPFION
EEDDPSZRNAVYMMTATBDZQSOEMUVNPPPSUACBAZUXMHECTHLEGRPUNKDMBPPW
EQTGJOPARMOWZDQYOXYTJBBHAWDYDCPRJBXPHOOHPKWQYUHRQZHNBNFUVQNQ
QLRZJPXIOGVLIEXDZUZOSRKRUSVOJBRZMWZPOWKJILEFRAAMDIGPNPUUHGXP
QNJWJMWAXXMNSNHHLQQRZUDLTFZOTCJTNZXUGLSDSMZCNOCKVFAJFRMXOTHO
WKBJZWUCWLJFRIMPMYHCHZRIWKBARXBGFCBCEYHJUGIXWTBVTREHBBCPXIFB
XVFBCGKCFQCKCOTZGKUBMJRMBSZTSSHFROEFWSJRXJHGUZYUPZWWEIQURPIX
IQFLDUUVEOOWQCUDHNEFNJHAIMUCZFSKUIDUBURISWTBRECUYKABFCVKDZEZ
TOIDUKUHJZEFCZZZBFKQDPQZIKFOBUCDHTHXDJGKJELRLPAXAMCEROSWITDP
TPCCLIFKELJYTIHRCQAYBNEFXNXVGZEDYYHNGYCDRUDMPHMECKOTRWOSPOFG
HFOZQVLQFXWWKMFXDYYGMDCASZSGOVSODKJGHCWMBMXRMHUYFYQGAJQKCKLZ
NAYXQKQOYZWMYUBZAZCPKHKTKYDZIVCUYPURFMBISGEKYRGZVXDHPOAMVAFY
RARXSVKHTQDIHERSIGBHZJZUJXMMYSPNARAEWKEGJCCVHHRJVBJTSQDJOOTG
PKNFPFYCGFIEOWQRWWWPZSQMETOGEPSPXNVJIUPALYYNMKMNUVKLHSECDWRA
CGFMZKGIPDFODKJMJQWIQPUOQHIMVFVUZWYVIJGFULLKJDUHSJAFBTLKMFQR
MYJFJNHHSSQCTYDTEAMDCJBPRHTNEGYIWXGCJWLGRSMEAEARWTVJSJBAOIOJ
LWHYPNVRUIHOSWKIFYGTYDHACWYHSGEWZMTGONZLTJHGAUHNIHREQGJFWKJS
MTPJHAEFQZAAULDRCHJCCDYRFVVRIVUYEEGFIVDRCYGURQDREDAKUBNFGUPR
OQYLOBCWQXKZMAUSJGMHCMHGDNMPHNQKAMHURKTRFFACLVGRZKKLDACLLTEO
JOMONXRQYJZGINRNNZWACXXAEDRWUDXZRFUSEWJTBOXVYNFHKSTCENAUMNDD
XFDMVZCAUTDCCKXAAYDZSXTTOBBGQNGVVPJGOJOGLMKXGBFCPYPCKQCHBDDZ
WRXBZMQRLXVOBTWHXGINFGFRCCLMZNMJUGWWBSQFCIHUBSJOLLMSQSGHMCPH
ELSOTFLBGSFNPCUZSRUPCHYNVZHCPQUGRIWNIQXDFJPWPXFBLKPNPEELFJMT

答案提交

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

个人题解

276

由于输入量较大,使用IO流进行读取数据,存储到List中,每个元素代表一行的数据,剩下的只需要暴力枚举。

public class Main {
    
    

    public static void main(String[] args) {
    
    
        String filePath = "D:\\蓝桥杯\\src\\question01\\in.txt";
        List<String> strings = getInList(filePath);
        int count = 0;//记录山谷数
        //暴力枚举筛选结果
        for (int i = 1; i < strings.size()-1; i++) {
    
    //第一行和最后一行不再枚举
            for (int j = 1; j < strings.get(i).length()-1; j++) {
    
    //第一列和最后一列不再枚举
                if (strings.get(i).charAt(j) < strings.get(i-1).charAt(j)
                && strings.get(i).charAt(j) < strings.get(i+1).charAt(j)
                && strings.get(i).charAt(j) < strings.get(i).charAt(j-1)
                && strings.get(i).charAt(j) < strings.get(i).charAt(j+1)){
    
    
                    ++count;
                }
            }
        }
        System.out.println(count);
    }

    //以列表的形式获取文件数据
    public static List<String> getInList(String filePath){
    
    
        BufferedReader bufferedReader = null;
        List<String> res = new ArrayList<>();
        try {
    
    
            bufferedReader = new BufferedReader(new FileReader(filePath));
            String line;
            while ((line = bufferedReader.readLine()) != null){
    
    
                res.add(line);//将字符存储进列表
            }
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            return res;
        }
    }
}

E 最小矩阵

问题描述

小蓝有一个 100 行 100 列的矩阵,矩阵的左上角为 1。其它每个位置正好比其左边的数大 2,比其上边的数大 1 。
例如,第 1 行第 2 列为 3,第 2 行第 2 列 为 4,第 10 行第 20 列为 48。
小蓝想在矩阵中找到一个由连续的若干行、连续的若干列组成的子矩阵,使得其和为 2022,请问这个子矩阵中至少包含多少个元素(即子矩阵的行数和列数的乘积)。

答案提交

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

个人题解

12

本题可以使用二维前缀和去模拟,当然也可以直接暴力,毕竟填空题(手动狗头)。
这里提供 二维前缀和 的方式:

/**
 * @author 兴趣使然黄小黄
 * @version 1.0
 * 利用前缀和解决
 */
public class Main {
    
    

    public static void main(String[] args) {
    
    
        int[][] arr = getArr();
        int[][] prefixArr = getPrefixArr(arr);//获取前缀和数组
        int minCount = Integer.MAX_VALUE;//记录最小矩阵元素个数
        for (int x1 = 0; x1 < 100; x1++) {
    
    
            for (int y1 = 0; y1 < 100; y1++) {
    
    
                for (int x2 = 0; x2 < 100; x2++) {
    
    
                    for (int y2 = 0; y2 < 100; y2++) {
    
    
                        int temp = getSum(prefixArr, x1, y1, x2, y2);
                        //满足题意
                        if (temp == 2022){
    
    
                            int count = (y2 - y1 + 1) * (x2 - x1 + 1);
                            minCount = Math.min(minCount, count);
                        }
                        if (temp > 2022){
    
    
                            break;//剪枝
                        }
                    }
                }
            }
        }
        System.out.println(minCount);
    }

    //初始化数组
    public static int[][] getArr(){
    
    
        int[][] arr = new int[100][100];
        for (int i = 0; i < arr.length; i++){
    
    
            for (int j = 0; j < arr[i].length; j++) {
    
    
                if(i == 0 && j == 0){
    
    
                    arr[i][j] = 1;
                    continue;
                }
                if (j == 0){
    
    
                    arr[i][j] = arr[i-1][j] + 1;
                    continue;
                }
                arr[i][j] = arr[i][j-1] + 2;
            }
        }
        return arr;
    }

    //由前缀和数组获取区域和
    public static int getSum(int[][] prefixArr, int x1, int y1, int x2, int y2){
    
    
        if (x1 - 1 < 0 && y1 - 1 < 0){
    
    
            return  prefixArr[x2][y2];
        }
        if (x1 == 0){
    
    
            return prefixArr[x2][y2] - prefixArr[x2][y1 - 1];
        }
        if (y1 == 0){
    
    
            return prefixArr[x2][y2] - prefixArr[x1 - 1][y2];
        }
        return prefixArr[x2][y2] - prefixArr[x1-1][y2] - prefixArr[x2][y1-1] + prefixArr[x1-1][y1-1];
    }

    //构造二维前缀和数组
    public static int[][] getPrefixArr(int[][] arr){
    
    
        int[][] prefixArr = new int[arr.length][];
        for (int i = 0; i < arr.length; i++) {
    
    
            prefixArr[i] = new int[arr[i].length];
            for (int j = 0; j < arr[i].length; j++) {
    
    
                if (i == 0 && j == 0){
    
    
                    prefixArr[i][j] = arr[i][j];
                }else if (i == 0){
    
    
                    prefixArr[i][j] = prefixArr[i][j-1] + arr[i][j];
                }else if (j == 0){
    
    
                    prefixArr[i][j] = prefixArr[i-1][j] + arr[i][j];
                }else {
    
    
                    prefixArr[i][j] = prefixArr[i-1][j] + prefixArr[i][j-1] + arr[i][j] - prefixArr[i-1][j-1];
                }
            }
        }
        return prefixArr;
    }
}

如果小伙伴对一维二维前缀和与差分数组不理解的,可以参考一下这位up主的视频,比较细致:前缀和与差分
这里就不再对二维前缀和数组的构造和计算区间的原理进行额外的叙述啦!


F 核酸日期

问题描述

如果周一做核酸,周二显示核酸天数为 1 天,周三显示 2 天,以此类推,周六显示 5 天,周日显示 6 天。
小蓝在某一天做了一次核酸,请问他的核酸显示为几天。已知做核酸和查看核酸不是在同一天,而且相差不超过 6 天(显示的数为 1 到 6 之间的数)。

输入格式

输入第一行包含一个整数 s ,表示小蓝做核酸是周几。 s 为 1 到 6 依次表示周一到周六,s 为 7 表示周日。
第二行包含一个整数 t ,表示查看核酸是周几。 t 为 1 到 6 依次表示周一到周六,t 为 7 表示周日。

输出格式

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

样例输入

5
2

样例输出

4

评测用例规模与约定

对于所有评测用例, 1 < = s , t < = 7 1 <= s, t <= 7 1<=s,t<=7。

个人题解

import java.util.Scanner;


public class Main {
    
    

    public static void main(String[] args) {
    
    
        Scanner input = new Scanner(System.in);
        int s = input.nextInt();//表示周几做核酸
        int t = input.nextInt();//表示周几查看
        int res = 0;
        if(t > s){
    
    
            res = t - s;
        }else {
    
    
            res = t + 7 - s;
        }
        System.out.println(res);
        input.close();
    }
}

G 英文转换

问题描述

输入一个由小写英文字母组成的字符串,请将其中的元音字母(a, e, i, o, u)转换成大写,其它字母仍然保持小写。

输入格式

输入一行包含一个字符串。

输出格式

输出转换后的字符串。

样例输入

lanqiao

样例输出

lAnqIAO

评测用例规模与约定

对于所有评测用例,字符串的长度不超过100。

个人题解

import java.util.Scanner;


public class Main {
    
    

    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        String inputString = scanner.next();//接收一个字符串
        String resultString = getResString(inputString);
        System.out.println(resultString);//打印结果
        scanner.close();
    }

    //判断是否为元音字母
    public static boolean judge(char c){
    
    
        if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'){
    
    
            return true;
        }
        return false;
    }

    //遍历一个字符串,对字符串中的元音字母进行处理,将所有的元音字母转换成为大写
    public static String getResString(String s){
    
    
        char[] charArray = s.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
    
    
            if (judge(charArray[i])){
    
    
                charArray[i] = (char) (charArray[i] - 32);
            }
        }
        return new String(charArray);
    }
}

H 充电器

问题描述

小蓝有一个充电器,可以使用不同的电压和电流充电。
给定充电器工作的记录,请计算在这个记录期间总共通过充电传输了多少电能。

输入格式

输入第一行包含一个整数 n , 表示记录的条数。
接下来 n 行,每行包含一个时刻 T 和两个非负整数 U, I,表示在时刻 T 充电电压变为 U(单位伏),电流变为 I(单位A)。最后一行满足 U 和 I 均为 0,在前面的行中也可能出现 U、I 为 0 的情况。其中时间表示为 HH:MM:SS 的格式,时分秒分别用两位十进制数表示(补前导零)。
输入保证时刻依次递增且在 00:00:00 至 23:59:59 的区间内,不用考虑跨过零点充电的情况。

输出格式

输出一个整数,表示总共通电的电能为多少焦耳,其中 1 焦耳等于 1 伏乘以1 安乘以 1 秒。

样例输入

3
12:00:00 12 1
12:01:02 5 2
12:01:10 0 0

样例输出

824

评测用例规模与约定

对于所有评测用例, 1 < = n < = 100 , 0 < = U , I < = 100 1 <= n <= 100, 0 <= U, I <= 100 1<=n<=100,0<=U,I<=100。

个人题解

import java.util.Scanner;


public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner in = new Scanner(System.in);
        long res = 0L;//用于保存结果,使用long防止数过大溢出
        int N = in.nextInt();//表示接下来有多少行输入
        String[] inputTime = new String[N];
        int[] U = new int[N];
        int[] I = new int[N];
        //接收输入
        for (int i = 0; i < N; i++) {
    
    
            inputTime[i] = in.next();
            U[i] = in.nextInt();
            I[i] = in.nextInt();
        }
        //计算电量
        for (int i = 1; i < inputTime.length; i++) {
    
    
            //每次计算需要两行数据
            int time = getTimes(inputTime[i-1], inputTime[i]);
            res += time * U[i-1] * I[i-1];
        }
        //打印结果
        System.out.println(res);
        in.close();
    }

    //以秒返回相邻两段输入的时间间隔,便于计算
    public static int getTimes(String startTime, String endTime){
    
    
        //将获取的时间分别以:分隔存储,0索引对应的是小时,1索引对应的是分钟,2索引对应的秒
        String[] splitStartTime = startTime.split(":");
        String[] splitEndTime = endTime.split(":");
        int start = myParse(splitStartTime[0]) * 3600 + myParse(splitStartTime[1]) * 60
                + myParse(splitStartTime[2]);
        int end = myParse(splitEndTime[0]) * 3600 + myParse(splitEndTime[1]) * 60
                + myParse(splitEndTime[2]);
        return end - start;
    }

    //对每一个字符进行处理,例如00处理为0
    public static int myParse(String s){
    
    
        char[] chars = s.toCharArray();
        if(chars[0] == '0'){
    
    
            return Integer.valueOf(String.valueOf(chars[1]));
        }
        return Integer.valueOf(s);
    }
}

猜你喜欢

转载自blog.csdn.net/m0_60353039/article/details/127816266