2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。
给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
输入描述
输入包含一个八位整数 N N,表示日期。
对于所有评测用例,10000101 \leq N \leq 8999123110000101≤ N≤89991231,保证 N N 是一个合法日期的 8 位数表示。
输出描述
输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
输入输出样例
输入:
20200202
输出
20211202
21211212
思路:输入一个字符串yyyymmdd,获取yyyy子串,将该子串反转再合并,就得到一个回文数,该回文数首先应该大于原始的yyyymmdd。因为一个年份对应一个回文数(月日就是把年份反过来),所以将年份提取,用for循环,依次往后找答案。先判断该回文数是否是合法日期,再判断是否为ABABBABA型日期。要建立一个数组存放每个月的天数,构造一个函数判断闰年,修改二月份的天数。构造一个函数判断ABABBABA型回文日期。ans1存下一个回文日期,ans2存下一个ABABBABA型回文日期。
知识点:
1、substr(a,b):获取从下标a开始的b个字符的子串
例如:S="apple",s=S.substr(0,3),则s="app"
2、stoi():将字符串转变为数字
例如:str="1234";int ans=stoi(str)
3、to_string():将数字转变为字符串
4、reverse():将字符串反转
5、字符串拼接:+
代码(含注释):
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int D[13] = {-1 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31};//每个月的天数
bool checkLeapYear(int y){//判断闰年
if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) return true;
return false;
}
bool checkABABBABAstyle(string s){//判断是否为ABABBABA型
if(s[0] == s[2] && s[0] == s[5] && s[0] == s[7] && s[1] == s[3] && s[1] == s[4] && s[1] == s[6]) return true;
return false;
}
int main()
{
string S , ans1, ans2;
string s,t,year;
int y,m,d,i;
cin >> S;
year=S.substr(0,4);
for(i =stoi(year) ; ans1 == "" || ans2 == "" ; i ++){
//i 初值为输入数据的年
// 找到了ans1和ans2,循环结束,有任何一个没有找到 就要继续循环寻找
s = to_string(i) , t = to_string(i);//s为当前枚举的年
reverse(t.begin() , t.end());//求i的逆
s += t;//构造拼接出 s+s' 年月日
if(s <= S) continue ;//构造出的s 小于起始日期,不计,
//用continue 直接进入下一轮循环,考察下一年,下面的语句不执行。
y = stoi(s.substr(0 , 4)) , m = stoi(s.substr(4 , 2)) , d = stoi(s.substr(6 , 2));
//从回文串中获得年月日:y、m、d。
if(checkLeapYear(y)) D[2] = 29;//如果是闰年,2月的天数为29,
if(m < 1 || m > 12) continue ;//如果月m不在1到12之间,就不是合法月份,
//然后进入下一轮循环。
if(d < 1 || d > D[m]) continue ;//如果d不在1到D[m]之间,就不是合法日期。
if(ans1 == "") ans1 = s;//s是合法日期的回文串,记录在ans1中
if(checkABABBABAstyle(s) && ans2 == "") ans2 = s;//s还符合ABABBABA型,记录在ans2中。
}
cout << ans1 << '\n' << ans2 << '\n';
return 0;
}
欢迎提问和指正~