zl程序教程

您现在的位置是:首页 >  后端

当前栏目

【蓝桥杯Java组】Java选手做填空题时不得不会的API

JAVAAPI 蓝桥 不得不 填空题
2023-09-11 14:20:00 时间

1

🍋前言

🎈🎈🎈蓝桥杯的填空题相比起程序题来说还是要简单一些的,而且Java提供了丰富的API供我们使用,学会一些额外的Java API有助于我们在解决问题时更加简单直接,尤其是Java中的字符串类,日期类这两个在填空题中经常与我们见面的两个类。善于利用Java自带的API可以减少思考问题的时间,让问题变得更加简单直观,为我们后面解决程序题争取更多的时间~

👉🏻题目传送门:

门牌制作https://www.lanqiao.cn/problems/592/learning
回文日期https://www.lanqiao.cn/problems/498/learning
猜生日https://www.lanqiao.cn/problems/738/learning
棋盘放麦子https://www.lanqiao.cn/problems/739/learning

1.StringBuilder、StringBuffer可变字符串类☕

StringBuilder与StringBuffer都是可变字符串,可以让我们在处理字符串问题时更加灵活。

两者的区别在于StringBuilder效率高但是线程不安全,而StringBuffer效率低但是线程安全。

在蓝桥杯中一般使用StringBuilder,速度更快。🚀🚀🚀

StringBuilder、StringBuffer基础用法

  • 构造方法:

    StringBuilder sb = new StringBuilder("abcefg");

  • 在字符串末尾追加内容:

    sb.append("123");

    结果:

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abcefg");
        sb.append("123");
        System.out.println(sb);
    }
    
    abcefg123
    
  • 获取字符串长度:

    sb.length();

  • 获取指定位置的一个字符(下标从0开始):

    char c = sb.charAt(1);

    结果:

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abcefg");
        char c = sb.charAt(1);
        System.out.println(c);
    }
    
    b
    
  • 获取指定子串的下标:

    int index = sb.indexOf("ce");

    结果:

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abcefg");
        int index = sb.indexOf("ce");
        System.out.println(index);
    }
    
    2
    
  • 反转字符串:

    sb.reverse();

    结果:

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abcefg");
        sb.reverse();
        System.out.println(sb);
    }
    
    gfecba
    
  • 在指定位置的前面插入内容:

    sb.insert(1, 123);

    结果:

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abcefg");
        sb.insert(1, 123);
        System.out.println(sb);
    }
    
    a123bcefg
    
  • 将区间内的字符删除(区间左闭右开):

    sb.delete(1, 3);

    结果:

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abcefg");
        sb.delete(1, 3);
        System.out.println(sb);
    }
    
    aefg
    
  • 将区间内的字符替换为指定字符串(区间左闭右开):

    sb.replace(1, 3, "666");

    结果:

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("abcefg");
        sb.replace(1, 3, "666");
        System.out.println(sb);
    }
    
    a666efg
    

例题:

✨门牌制作✨

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小蓝要为一条街的住户制作门牌号。

这条街一共有 2020位住户,门牌号从 1 到 2020 编号。

小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。

请问要制作所有的 1 到 2020号门牌,总共需要多少个字符 2?

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

👩🏻‍🏫使用C或C++的同学可能第一时间想到的是用取余法分别对每一位进行判断,然而Java选手使用字符串可以更轻易的解决~🤣

这道题其实不需要考虑内存的问题,直接使用String就行。

public class Main {
    
    public static void main(String[] args) {
        int num = 1, count = 0;
        while (num <= 2020) {
            String numStr = new String("" + num);
            for (int i = 0; i < numStr.length(); i++) {
                if (numStr.charAt(i) == '2')
                    count++;
            }
            num++;
        }
        System.out.println(count);
    }

}
✨回文日期✨

题目描述

2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。

有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。

也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。

给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。

输入描述

输入包含一个八位整数 NN,表示日期。

输出描述

输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。

输入输出样例

示例

输入

20200202

输出

20211202
21211212

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

👩🏻‍🏫这道题目是一道程序题,使用StringBuilder或者StringBuffer在逻辑上更加直观一些,并且直接调API会方便很多,可见Java的字符串玩的6有多重要。😎

详细的题解可以参考这篇文章:

蓝桥杯真题-回文日期(模拟 构造 2020 省赛)_

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        int ans1 = 0, ans2 = 0;
        boolean flag = false;
        while (true) {
            num = runTime(num);
            if (!flag && judge(num)) {
                ans1 = num;
                flag = true;
            }
            if (judge(num) && judge2(num)) {
                ans2 = num;
                break;
            }
        }
        System.out.println(ans1);
        System.out.println(ans2);
        scanner.close();
    }
    public static boolean judge(int num) {
        String string = Integer.toString(num);
        StringBuffer stringBuffer = new StringBuffer(string.substring(4));
        if (string.startsWith(stringBuffer.reverse().toString())) {
            return true;
        }
        return false;
    }
    public static boolean judge2(int num) {
        String string = Integer.toString(num);
        if (string.charAt(0) == string.charAt(2) && string.charAt(1) == string.charAt(3)) {
            return true;
        }
        return false;
    }
    public static int runTime(int num) {
        int year = num/10000, month = (num/100)%100, day = num%100;
        day++;
        if(day > 31) {
            day = 1;
            month ++;
            if (month > 12) {
                month = 1;
                year++;
            }
        }
        return year*10000+month*100+day;
    }
}

2.Calendar日期类📆

日期问题在蓝桥杯的填空题中经常出现,使用C或C++处理起来会很麻烦,而使用Java的同学掌握了Calendar类在解决日期问题上基本就相当于是开挂了~👩🏻‍🏫

Calendar基础用法

  • 使用当前时间获取Calendar对象:

    Calendar calendar = Calendar.getInstance();

  • 获取年份:

    int year = calendar.get(Calendar.YEAR);

  • 获取月份:

    月份是从0开始算起的,所以获取月份以后要加1才是真正的月份。

    int year = calendar.get(Calendar.YEAR);

  • 获取日期:

    int day = calendar.get(Calendar.DATE);

  • 除了年月日,还可以得到时分秒与星期,只需要改变get()中的参数即可。

    2

  • 修改日期:

    calendar.set(Calendar.xxx, 123);

  • 加一天(月、年):

    calendar.add(Calendar.DATE, 1);calendar.add(Calendar.MONTH, 1);calendar.add(Calendar.YEAR, 1);

例题:

✨猜生日✨

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

今年的植树节(2012 年 3 月 12 日),小明和他的叔叔还有小伙伴们一起去植树。休息的时候,小明的同学问他叔叔多大年纪,他叔叔说:“我说个题目,看你们谁先猜出来!”

“把我出生的年月日连起来拼成一个 8 位数(月、日不足两位前补 0)正好可以被今天的年、月、日整除!”

他想了想,又补充到:“再给个提示,我是 6 月出生的。”

根据这些信息,请你帮小明算一下,他叔叔的出生年月日。

格式是年月日连成的 8 位数。例如,如果是 1948 年 6 月 12 日,就写:19480612。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

👩🏻‍🏫这道题使用日期模拟会更直观一些,从1912年开始模拟日期,判断每一天是否满足条件即可。由于题目要求月日不足2位用0补齐,可以先使用StringBuilder将年月日拼接起来再转换为整数,判断条件时注意能被3整除就一定能被12整除即可。

 java.util.Calendar;

public class Main {
    
    public static void main(String[] args) {
//        叔叔肯定不会超过100岁,从1912年算起
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, 1912);
        while (calendar.get(Calendar.YEAR) < 2012) {
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1;
            int day = calendar.get(Calendar.DATE);
            StringBuilder num = new StringBuilder();
            num.append(year);
            num.append(month < 10 ? "0" + month : month);
            num.append(day < 10 ? "0" + day : day);
            int numInt = Integer.parseInt(num.toString());
            if (numInt % 2012 == 0 && month == 6 && numInt % 12 == 0) {
                System.out.println(numInt);
                break;
            }
            calendar.add(Calendar.DATE, 1);
        }

3.BigDecimal大数计算类📏

在Java中最多支持64位整数也就是long型,但如果要表示并且计算超过这个整数范围的数,可以使用BigInteger或者BigDecimal这两个类来解决。BigDecimal除了支持表示整数外还能进行高精度的小数运算,比如我们直接判断0.1 + 0.2 == 0.3会得到结果false,这是由于二进制无法精确的小数造成的,使用BigDecimal也可以规避小数在二进制表示上的误差。

这个类的出镜频率没有StringBuilder和Calendar那么高,但是为了以防万一还是有必要了解一下的。

BigDecimal基础用法

  • 构造方法(参数一般使用字符串):

    BigDecimal a = new BigDecimal("0.1");

    BigDecimal b = new BigDecimal("0.2");

  • 加减乘除:

    BigDecimal c = a.add(b);

    BigDecimal c = a.subtract(b);

    BigDecimal c = a.multiply(b);

    BigDecimal c = a.divide(b);

  • 取绝对值:

    BigDecimal c = a.abs();

  • n次幂:

    BigDecimal c = a.pow(n);

例题:

✨棋盘放麦子✨

题目描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

你一定听说过这个故事。国王对发明国际象棋的大臣很佩服,问他要什么报酬,大臣说:请在第 1 个棋盘格放 1 粒麦子,在第 2 个棋盘格放 2 粒麦子,在第 3 个棋盘格放 4 粒麦子,在第 4 个棋盘格放 8 粒麦子,…后一格的数字是前一格的两倍,直到放完所有棋盘格(国际象棋共有 64 格)。

国王以为他只是想要一袋麦子而已,哈哈大笑。

当时的条件下无法准确计算,但估算结果令人吃惊:即使全世界都铺满麦子也不够用!

请你借助计算机准确地计算,到底需要多少粒麦子。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

👩🏻‍🏫题目本身不难,但是缺德就缺德在结果超出整型表示范围了,如果不知道BigDecimal或者BigInteger的话会不太容易解决。

import java.math.BigDecimal;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //在此输入您的代码...
        BigDecimal ansBigDecimal = new BigDecimal("0");
        BigDecimal tempBigDecimal = new BigDecimal("1");
        for (int i = 0; i < 64; i++) {
            ansBigDecimal = ansBigDecimal.add(tempBigDecimal);
            tempBigDecimal = tempBigDecimal.multiply(new BigDecimal("2"));
        }
        System.out.println(ansBigDecimal.toString());
        scan.close();
    }
}