题目描述
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。
给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
输入描述
输入包含一个八位整数 NN,表示日期。
对于所有评测用例,10000101 \leq N \leq 8999123110000101≤N≤89991231,保证 NN 是一个合法日期的 8 位数表示。
输出描述
输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
首先说一句,这大模拟是真恶心噢,很简单的思路我做了一个小时,其中要考虑到很多的优先级问题,因为如果他是一个ABABBABA的回文,那么它必定就是回文数字,并且第一次出现,我们就要设置两个哨兵了,一个记录是否已经输出了第一个回文日期,一个记录是否输出了ABABBABA型的,总之题目很简单,就是多了很多的细节,比如一个合法的日期判定什么的要打很长一段时间~~总体还是个简单题吧,就是代码量大了点。具体思路看注释。
#include<bits/stdc++.h>
using namespace std;
int a;
bool check1(int y,int m,int d){ //合法日期判断,懂得读懂
if(y%400==0||(y%4==0&&y%100!=0)){ //闰年特判一下2月有29天
if(m==2&&d<=29)return true;
else if(m==1||m==3||m==5||m==7||m==8||m==10||m==12){
if(d<=31)return true;
}
}else{
if(m==2&&d<=28)return true; //否则只有28天
else if(m==1||m==3||m==5||m==7||m==8||m==10||m==12){ //判断大小月
if(d<=31)return true;
}else if(m==4||m==6||m==9||m==11){
if(d<=30)return true;
}
}
return false; //如果都不符合,那么不是合法的,最后返回false
}
int check(int x){
int y,m,d,t,s,t1,s1;
y=x/10000; //获取年月日
m=x%10000,m/=100;
d=x%100;
t1=m;s1=d; //暂存年月日
t=m%10;t*=10;m/=10;m+=t; //月分反转
s=d%10;s*=10;d/=10;d+=s; //日反转
if(m==y%100&&d==y/100&&check1(y,t1,s1)){ //判断反转了的是否和年能够匹配上,并且是否合法日期
if(m==d&&y%100==m&&d==y/100)return 2; //在判断一下是不是ABABBABA型
return 1;
}
return 0;
}
int main(){
cin>>a;
int flag=0,cc=0; //设置两个好朋友(哨兵)
for(int i=a+1;i<=89999999;i++){ //从当前数一直到封顶
if(check(i)==1||check(i)==2){ //如果返回的是1或者2,说明是个回文日期
if(check(i)==2){ //如果返回的是2
if(!cc)cout<<i<<endl; //判断是否输入过第一个出现的回文日期,如果没有的话这个就是第一个
cout<<i; //并且输出ABABBABA型回文日期
flag=1; //标记为已输出
}else if(!cc){ //否则就不是ABABBABA型,我们直接输出该回文日期,并且将第一次给夺走~
cout<<i<<endl;
cc=1;
}
}
if(flag)break; //如果连ABABBABA都输出过了,那么肯定都输出完了,直接结束即可
}
return 0;
}