题目描述
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2
日。
因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8
位数是 20200202,恰好是一个回文数。
我们称这样的日期是回文日期。
有人表示 20200202 是“千年一遇” 的特殊日子。
对此小明很不认同,因为不到 2
年之后就是下一个回文日期:20211202 即 2021 年 12 月 2
日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。
对此小明也不认同,因为大约 100
年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12
日。
算不上“千年一遇”,顶多算“千年两遇”。
给定一个 8
位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
注意
下一个回文日期和下一个 ABABBABA 型的回文日期可能是同一天。
ABABBABA 型的回文日期,需要满足 A≠B
。
样例
输入样例:
20200202
输出样例:
20211202
21211212
思路
枚举从输入年份到9999年判断符合要求的日期。
例如 2021 a,b,c,d分别取个1,十2,百0,千位2,则a*1000+b*100+c*10+d必然等于对应的年份,即2021abcd必然构成回文日期。
因此只要判断月份(a*10+b)是否在1~12,日期是否在对应月份的日期范围,同时注意闰年。
C++ 代码
#include<iostream>
using namespace std;
bool check(int y);
bool check1(int y);
int n;
int moth1[32]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int moth2[32]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool isryear(int year){
return ((year%400!=0&&year%4==0)||year%400==0);//判断闰年
}
bool check1(int y){
int a=y%10;
int b=y/10%10;
int c=y/100%10;
int d=y/1000;
if(a==b)return false;
if(a!=c||b!=d)return false;//判断年份是否符合ABAB要求
else return check(y);
}
bool check(int y){
int a=y%10;
int b=y/10%10;
int c=y/100%10;
int d=y/1000;
if(a*10+b>12)return false;//判断月份
if(isryear(y)){
if(c*10+d>moth2[a*10+b])return false;
}
else {
if(c*10+d>moth1[a*10+b])return false;
}
//判断日期是否在对应月份的日期范围内
if(y*10000+a*1000+b*100+c*10+d<=n)//找到的回文日期是否在输入日期之前
{return false;}
else{ cout<<y<<a<<b<<c<<d;
return true;}
}
int main(){
cin>>n;
int a1=n/10000;
for(int i=a1;i<=9999;i++){
if(check(i)){break;}
}cout<<endl;
for(int i=a1;i<=9999;i++) if(check1(i))break;
}