题解 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;
}
点个赞~~