好吧,感觉自己再一次被坑了
题意
给你两个日期a
和b
(八位数YYYYMMDD
),求这两个日期中间(包括这两个日期本身)有多少个日期是回文的。
例如 输入:20000101 20101231
输出:2
(20011002
和20100102
是符合要求的)
思路1
第一个想到的是直接枚举a
和b
之间的整数,判断是否为合法的日期,再判断是否为回文串。
#include<bits/stdc++.h>
using namespace std;
int b,e;
long long ans=0;
bool judge(int date){
int s=0,t=date;
while(t>0){
s=s*10+t%10;
t/=10;
}
if(date==s) return true;
else return false;
}
int day(int year,int month){
if(month<8){
if(month%2==1) return 31;
else if(month==2){
if(year%100!=0&&year%4==0) return 29;
else return 28;
}
else return 30;
}
if(month>=8){
if(month%2==0) return 31;
else return 30;
}
}
bool judge2(int date){
int y=date/10000;
int m=date/100%100;
int d=date%100;
if(d>day(y,m)||d<1) return false;
if(m>12||m<1) return false;
return true;
}
int main(){
cin>>b>>e;
if(b==e){
cout<<judge(b)<<endl;
return 0;
}
for(int num=b;num<=e;num++)
if(judge2(num))//判日期合法
if(judge(num))//判回文
ans++;
cout<<ans<<endl;
return 0;
}
这其实是我两年之前写的代码,当时我才学了c++没多久,代码也是又臭又长。
思路2
如果换一种枚举方式,先保证他是回文串,月份和日期合法,再判断日期是否在a
和b
之间,就会简单很多。我们枚举月和日,再把年份通过回文算出来,比如10月12日,也就是1012
,对应的年份就是2101
,拼起来是21011012
,是回文串。
这个时候会遇到一个问题:闰年怎么办?
别慌,闰年与平年唯一的不同就是2月29号,变成数字串0229
,它所对应的年份是9220
,确实是闰年,所以只要最后判断一下92200229
是否在a
和b
之间就行了。
#include<bits/stdc++.h>
using namespace std;
int a,b,ans,D[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main(){
cin>>a>>b;
for(int i=1;i<=12;i++)
for(int j=1;j<=D[i];j++){
int y=j%10*1000+j/10*100+i%10*10+i/10;
//将月和日拆分成一个个数字后再倒着组合成年份
int date=y*10000+i*100+j;
if(date>=a&&date<=b) ans++;
}
int date=92200229;
if(date>=a&&date<=b) ans++;
printf("%d\n",ans);
return 0;
}
这就舒服多了嘛!(觉得自己特别聪明)