回文日期(蓝桥杯C/C++)超详解

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;
}

欢迎提问和指正~

  • 11
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值