第一期
日期专题 
冲刺蓝桥杯省一模板大全来啦
~
蓝桥杯4月8号就要开始了
~
还没背熟模板的伙伴们背起来

祝大家4月8号蓝桥杯上岸
~
不清楚蓝桥杯考什么的点点下方
考点秘籍
想背纯享模版的伙伴们点点下方
蓝桥杯省一你一定不能错过的模板大全(第一期)
蓝桥杯省一你一定不能错过的模板大全(第二期)
想背注释模版的伙伴们点点下方
蓝桥杯必背第一期
蓝桥杯必背第二期
想看JavaB组填空题的伙伴们点点下方 
填空题
历年的蓝桥杯都非常喜欢出日期类题目,将此作为专题复习是很有必要的 
下面我们开始刷经典真题吧 
真题1 星期计数
刚开始看到这道题不知怎么做好?
那不知道怎么做怎么办?
看了一些网上的博客直接列出代码
实际上不利于初学者!
不会做没关系,我带你做,虽然我也很菜
不过竞赛竞赛,粤菜粤爱打,我们心态要乐观积极。
心态和实力你总得占一个吧
希望大家都是既有实力又是Lucky的那颗星星 
万物始于枚举!!!
题目问我们20的22次方后是星期几?
我们开始枚举:
今天是星期六,星期六1天后为星期七(星期日,不过是换一种说法)。
2天后为星期1
3天后为星期2
4天后为星期3
结合一星期7天,我们可以得出规律:
1天的暂时不考虑
先看2天以上的
2天后为星期1:6+2%7=1
3天后为星期2:6+3%7=2
4天后为星期3:6+4%7=3
看到这里聪明的小伙伴发现
6+n天后%7=对应的星期几
1天的怎么看?直接加即可!
因为星期7是在一周的范围内。所以是合法的。
有小伙伴会问万一算到最后得出的是8、9、10等等天数怎么办?
那就再对7取模,为什么?
星期8是不是就是星期七(天)的后一天即星期一即8%7=1
星期9是不是就是星期七(天)的后两天即星期二即9%7=2
星期10是不是就是星期七(天)的后一天即星期一即10%7=3
这样处理最后答案一定是合法正确的!!!
考虑到周六一天后直接加1的情况
代码可以这样写:6+(20^22)%7
在一周七天的合法范围内,最后答案为7
可能有小伙伴会这样问:可以这样写(6+20^22)%7=7?
如果得出的数是大于7说明他里面还有一周需要再取模!
像得到8、9、10等等,我们直接对7取模即可。
8%7==1、9%7==2、10%7==3又将答案返回到合法区间内且答案正确(上述验证)
可以!
不过你需要判断一下,这里是加上6再取模得到的结果
如果最终会得到0的话,是因为(6+1)%7=0
0的话也没关系,说明在星期一的前一天即星期7,答案正确!
这样是不是就成功拿下5分了,恭喜你离省一又近了一步 
写法1(大整数)
import java.util.*;
public class Main{
public static void main(String []args) {
Scanner sc=new Scanner(System.in);
int res=(int) Math.pow(20,22);
System.out.println(6+res%7);
}
}
写法2(循环求20^22,会溢出需要先取模)
import java.util.*;
public class Main{
public static void main(String []args) {
Scanner sc=new Scanner(System.in);
int res=1;
for(int i=1;i<=22;i++) {
res=(res*20)%7;
}
System.out.println(6+res);
}
}
真题2 时间显示
相同代码的不同的理解
理解1
import java.util.*;
public class Main{
static long n,h,m,s;
public static void main(String []args) {
Scanner sc=new Scanner(System.in);
n=sc.nextLong();
n/=1000;
//将毫秒舍去
n%=86400;
//一天24个小时,一个小时60分钟,一分钟60秒
//总计为24*60*60=86400
//天数不用输出,%保留一天的时分秒
h=n/3600;
// 1小时3600秒 /3600获得小时
n%=3600;
//保留最后的分秒
m=n/60;
//一小时60分,/60获得分钟
s=n%60;
//一分钟60秒,%60获得秒
System.out.printf("%02d:%02d:%02d",h,m,s);
}
}
理解2
import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
long n=sc.nextLong();
//毫秒
n/=1000;
//1s=1000ms,毫秒变成秒
//毫秒除以1000得到多少秒
n=n%86400;
//一天24个小时,1小时60分钟,1分钟60秒
//24*60*60=86400
//得到1个小时有多少秒
//1个小时有3600秒
long h=n/3600;
//1个小时3600秒,n除以3600得到多少个小时
n=n%3600;
//1个小时60分,1分60秒。取模后得到1个小时的分秒数
long m=n/60;
//一小时60分钟,n除以60得到多少分钟。
long s=n%60;
//一分钟60秒,n对60取模后得到多少秒
System.out.printf("%02d:%02d:%02d",h,m,s);
}
}
小结:
/
可以理解为取出前面的数位
%
可以理解为取出后面的数位
小技巧
这题采用格式化输出即printf
需要注意的是不足2位数即补0:%02d
真题3 特殊年份
字符串读入
不用去取各个位数,直接拿出字符串的各个字符
输入的字符串是左到右输入
输入:2023
千位:2 -->s.charAt(0)
同学们看过来,如果你也和我一样认为程序可以这样比的话。
恭喜你大错特错
正确形式:2 -->s.charAt(0)-'0'
注意:字符串中存的是每个字符或者每个字符的ASCII
码
可以是拿来做比较处理这没问题!
因为存的内容本质是不变的只是变化保存的形式。
但是如果直接取出来去运算或者输出结果就不是我们想要输出的答案了
我们看一下直接输出答案是什么?
再看一下正确修改后的情况:
很明显第二种才是我们想要的结果
因此,输入形式为字符串,内容为数字的。
如果是想比较是否相等的话可以直接比较
但如果是想要取出该数字记得转码:
s.charAt(0)-'0';
这样便可以获得想要的数字,即一开始我们理解的那样!
Accode(推荐)
耗时: 662 ms
import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int res=0;
for(int i=0;i<5;i++){
String s=sc.nextLine();
if(s.charAt(0)==s.charAt(2)&&s.charAt(1)==s.charAt(3)-1)res++;
}
System.out.println(res);
}
}
Accode2(String s=String.valueOf())
直接保留数字串的内容作为字符串
import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int cnt=0;
for(int i=0;i<5;i++){
int a=sc.nextInt();
String s=String.valueOf(a);
if(s.charAt(2)==s.charAt(0)&&s.charAt(3)==s.charAt(1)+1){
cnt++;
}
}
System.out.println(cnt);
}
}
字符串转字符数组
Accode
耗时: 641 ms
import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int res=0;
for(int i=0;i<5;i++){
char a[]=sc.next().toCharArray();
if(a[0]==a[2]&&a[1]==a[3]-1)res++;
}
System.out.println(res);
}
}
取数位
依次取出数字的千、百、十、个位数
直接比较即可
普遍做法(取数位)
耗时:726ms
import java.util.*;
public class Main{
public static void main(String []args){
Scanner sc=new Scanner(System.in);
int res=0;
int a[]=new int[5];
for(int i=0;i<5;i++){
a[i]=sc.nextInt();
int q=a[i]/1000;
//拿到千位数
int b=a[i]/100%10;
//拿到百位数
int s=a[i]/10%10;
//拿到十位数
int g=a[i]%10;
//拿到个位数
if(q==s&&g==b+1)res++;
}
System.out.println(res);
}
}
对于取数位的题目:我们实在不知道是 /还是%可以借助计算机来帮助我们列式
后续会出取数位的专题,敬请留意~
真题4 日期问题(第8届C++)
日期问题 
真题详解
类似真题:枚举的思想和处理方式类似
回文日期
ACcode
做完这两题会发现枚举的顺序很关键 
像日期问题这题:
我们是先去枚举他是否合法再去枚举他满不满足题目所给条件
而不是直接去枚举题目所给条件,那样太麻烦了。
像回文日期这题:
我们是先去枚举所有的回文数再去判断他是否合法
而不是直接去枚举日期是否满足回文数,那样太麻烦了。
此外,我们可以总结出一个模板用于判断年、月、日是否为合法日期。
跟着我一起背吧!!!
首先,我们先背诵一下日期。
平年:2月是28号
闰年:2月是29号
static int d[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
接着,这里需要注意的是参数可以变化 date-->year,month,day
static int d[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
public static boolean check(int date){
int year=date/10000;
int month=date/1000%100;
int day=date%100;
先判断月份是否合法
if(month==0)return false;
if(day==0||month!=2&&day>d[month])return false;
if(month==2){
int leap=0;
if(year%100!=0&&year%4==0||year%400==0)leap=1;
if(day>28+leap)return false;
}
return true;
}
背完模板了吗?
下面我们继续来练一下真题
真题5 回文日期
题目描述
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。
给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
输入描述
输入包含一个八位整数 N,表示日期。对于所有评测用例,10000101≤N≤89991231,保证 N 是一个合法日期的 8 位数表示。
输出描述
输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
实战
话不多说直接套模板,直接过了80%100的样例。
应该是有一些细节没考虑到,不过还是很开心(第一次套模板直接写出的题目)
蓝桥对于基础题还是需要细心一些尽快能地通过。
背模板(过8/10的样例)
import java.util.*;
public class Main{
static int d[]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
public static boolean check(int date) {
int year= date/10000;
int month=date%10000/100;
int day=date%100;
if(month==0||month>12)return false;
if(day==0||month!=2&&day>d[month])return false;
if(month==2) {
int leap=0;
if(year%100!=0&&year%4==0||year%400==0)leap=1;
if(day>28+leap)return false;
}
return true;
}
public static void main(String []args) {
Scanner sc=new Scanner(System.in);
int x =sc.nextInt();
int st=x/10000;
//先截取出年的数值
//便于去枚举回文串
int date1=10000101;
int date2=89991231;
//枚举回文串
for(int i=st+1;i<=8999;i++) {
//从下一年开始循环
//最小的四位即先截取出年的数值+1到8999
int date=i;
int a=date;
for(int j=0;j<4;j++) {
date=date*10+a%10;
a/=10;
}
//检验回文串是否合法
if(date1<=date&&date<=date2&&check(date)) {
System.out.println(date);
break;
}
}
//ABAB型
int date=st;
for(int i=st+1;i<=8999;i++) {
//从下一年开始循环
//最小的四位即先截取出年的数值+1到8999
//ABAB
String s=String.valueOf(i);
int a1=s.charAt(0)-'0';
int b1=s.charAt(1)-'0';
int a2=s.charAt(2)-'0';
int b2=s.charAt(3)-'0';
if(a1==a2&&b1==b2){
date=i;
int a=date;
for(int j=0;j<4;j++) {
date=date*10+a%10;
a/=10;
}
}
//检验回文串是否合法
if(date1<=date&&date<=date2&&check(date)) {
System.out.println(date);
break;
}
}
}
}
时间转换
题目描述:给定一个以秒为单位的时间t,要求用 “< H> :< M> :< S> ”的格式来表示这个时间。< H> 表示时间,< M> 表示分钟,而[HTML_REMOVED]表示秒,它们都是整数且没有前导的“0”。例如,若t=0,则应输出是“0:0:0”;若t=3661,则输出“1:1:1”。
Accode
import java.util.*;
public class Main{
public static void main(String []args) {
Scanner scanner=new Scanner(System.in);
int n= scanner.nextInt();
int h=n/3600;
//获得小时数
n=n%3600;
//获得60分钟内的秒数
int m=n/60;
//获得多少分钟
int s=n%60;
//获得多少秒
System.out.printf("%d:%d:%d",h,m,s);
}
}
提一个建议 字号可以小一点(真的太大啦!!
第一个怎么求出来20^22呢
同学你好,用的是Math.pow(20,22)。
也可以用循环方式求,不过数字太大会溢出,因此我们每算一次res就要先对7取模。和最后算出来再去取模答案是一样的。
不到最后都不能放弃!!!
本题解持续更新,后续会把刷到的经典题目放在上面!