P8716 [蓝桥杯 2020 省 AB2] 回文日期 题解

· · 题解

题目

解法

首先,这题是模拟题中的日期问题。显而易见

对于此题,我们可以进行如下分析:

其中,对于判断日期是否合法,我们可以进行如下分析:

对于判断回文日期,可以采用双指针算法,比较高级代码更为简洁。

对于判断特殊情况,直接在代码中给予说明。

#include<bits/stdc++.h>
using namespace std;
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//打个月份表
//判断合法 
bool check_valid(int date){
    int year=date/10000;
    int month=date%10000/100;
    int day=date%100;//分离年月日 
    if(day==0||month<=0||month>12)return false;//显然的不合法情况 
    if(month!=2&&day>months[month])return false;//月份不是2,day不合法就不合法 
    if(month==2){//月份是2 
        if((year%4==0&&year%100!=0)||(year%400==0))if(day>29)return false;//是闰月, day必须<=29 
        else if(day>28)return false;//是平月,day必须<=28 
    }
    return true;
}
//判断回文 
bool check_huiwen(string s){
    int len=s.size();
    for(int i=0,j=len-1;i<j;i++,j--)//i从前往后,j从后往前扫一遍 
        if(s[i]!=s[j])return false;//不对称,就不回文 
    return true;
}
//判断ABABBABA 
bool check_ABAB(string s){
    if(check_huiwen(s)){//首先它得是个回文数 
        //接下来只需判断前4位是否合法 
        if(s[0]!=s[2]||s[1]!=s[3]||s[0]==s[1])return false;
        //结合ABABBABA思考 
        return true;
    }
    return false;
}
int main(){
    int n;cin>>n;
    bool flag=0;
    for(int i=n+1;;i++){//枚举回文数 
        if(check_valid(i)){//合法 
            string s=to_string(i);//仅在C++11标准及以后出现,比较好用 
            if(check_huiwen(s)&&!flag){//输出第一个回文数 
                cout<<i<<endl;
                flag=1;
            }
            if(check_ABAB(s)){//输出第一个特殊回文数 
                cout<<i;
                return 0;
            }
        }
    }
    return 0;
}