🍋前言
🎈🎈🎈蓝桥杯的填空题相比起程序题来说还是要简单一些的,而且Java提供了丰富的API供我们使用,学会一些额外的Java API有助于我们在解决问题时更加简单直接,尤其是Java中的字符串类,日期类这两个在填空题中经常与我们见面的两个类。善于利用Java自带的API可以减少思考问题的时间,让问题变得更加简单直观,为我们后面解决程序题争取更多的时间~
👉🏻题目传送门:
门牌制作 | |
回文日期 | |
猜生日 | |
棋盘放麦子 |
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有多重要。😎
详细的题解可以参考这篇文章:
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()
中的参数即可。 - 修改日期:
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();
}
}