题解 P2010 【回文日期】

· · 题解

原来我做这道题时,自己写了一个Plus函数,WA了3个点 70分代码

#include<iostream>
using namespace std;

//10000101
//99991231
//-->331

int creat(int data){
    int ans=0,deal[9]={};
    for(int i=1;data>0;i++){
        deal[i]=data%10;
        data/=10;
    }
    for(int i=1;i<=8;i++){
        ans*=10;
        ans+=deal[i];
    }
    return ans;
}
int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int t,w,data,ans;
void Plus(){
    if((data%4000000==0)||((data/10000)%4==0&&data%1000000!=0)) day[2]=29;
    else day[2]=28;
    data+=1;
    if(data%100>day[(data/100)%100]){
        data-=data%100;
        data+=101;
        if((data/100)%100==13){
            data-=1200;
            data+=10000;
        }
    }
    return ;
}
int main(){
    cin>>t>>w;
    for(data=t;data<=w;data++){
        if(data==creat(data)) ans++;
        Plus();
    }
    cout<<ans;
    return 0;
}

自认为Plus写得没有错,但是不对 于是我疯了一把,三层大for一套,AC了……

思路讲解

我的三层大for先枚举年,再枚举月和日,最后将它们拼合,再看这个数是否是回文数就行了,唯一的问题就是有点慢,但这道题毕竟数据规模小,最大也就331ms,不会TLE

问题点:闰年问题

此处无需考虑闰年问题。因为闰年是0229,唯一可能是92200229,而9220是闰年,符合条件

UPD

本题解于2024年10月19日更新,现在已经可以通过最后的第11个点

#include<iostream>
using namespace std;
int creat(int data){//生成反过来的日期
    int ans=0,deal[9]={};
    for(int i=1;data>0;i++){//对日期进行拆解
        deal[i]=data%10;//取出最后一位
        data/=10;//删去最后一位
    }
    for(int i=1;i<=8;i++){//
        ans*=10;//前挪一位
        ans+=deal[i];//拼上最后一位
    }
    return ans;
}
int day[13]={0,31,29,31,30,31,30,31,31,30,31,30,31}/*每一个月的日期*/,t,w,ans;
int main(){
    cin>>t>>w;
    for(int k=t/10000;k<=w/10000;k++){//枚举年
        for(int i=1;i<=12;i++){//枚举月
            for(int j=1;j<=day[i];j++){//枚举日
                int tmp=k*10000+i*100+j;//拼合
        if(tmp<t||tmp>w) continue;
                if(tmp==creat(tmp)) ans++;//判断,自增
            }
        }
    }
    cout<<ans;//输出
    return 0;
}

点个赞~~