题目
思路
题意
假定日期的表示都是8位数字
给定一个日期范围,让我们计算在这个范围内,有多少个日期是回文的
解法
- 我们可能会去试着暴力枚举这两个日期间的所有日期,然后再判断有多少个日期是回文的,但是这样的日期处理非常的复杂,且不确定性很高,要做很多的细节处理
- 接着我们可以想到一个新的思路:
枚举所有8位数字组成的回文数(因为是回文的,所以只要枚举四位(因为不能含有前导零,所以就是枚举$1000$到$9999$)即可代替枚举8位)
判断该回文数是否在我们考虑的范围内
如果在范围内,再判断该8位数是否是一个合法的有意义的日期
细节处理
- 如何判断闰年
1.年份是可以被 400整除
2.年份可以被4整除,并且不能被100整除
代码
#include<iostream>
using namespace std;
int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //把1-12月的天数存下来
bool check_valid(int date)
{
int year=date/10000; //从date中拆分出年月日
int month=date%10000/100;
int day=date%100;
if(month==0||month>12) return false; //如果月份不合法,直接返回false
if(day==0||(month!=2&&day>days[month])) return false; //如果当前月份天数比实际的多,也不合法
if(month==2) //二月特判
{
int leap=(year%100&&year%4==0)||year%400==0;
if(day>28+leap) return false; //这里一开始我写错了写成了!=,其实不合法的情况是出现的天数,大于是实际该有的,小于的话其实是合法的,不等于的条件判断太大了
}
return true;
}
int main()
{
int date1,date2;
cin>>date1>>date2;
int res=0;
for(int i=1000;i<10000;i++) //枚举1000-9999的所有四位数,构成所有可能的8位回文序列
{
int date=i,x=i;
for(int j=0;j<4;j++) date=date*10+x%10,x/=10; //造回文数
if(date>=date1&&date<=date2&&check_valid(date)) res++; //符合条件的才能算
}
printf("%d",res);
return 0;
}