466. 回文日期
换一种思路,枚举所有的合法日期要比判断日期是否合法难很多。所以直接枚举回文数,在进行下面的操作
- 先枚举回文数,将4位数转化为8位回文数
- 判断是否在范围内 : min_date <= date <= max_date
- 判断日期是否合法 :月份在1~12 , day>=1且小于等于当月天数
这样的时间复杂度是只需要枚举1000~9999,106,一百万的复杂度。
1 . 如何将4位回文数转化为8位数字
12344321
可以看出是从后往前拼接,所以每次每次date = date * 10 + date % 10。
这里date是会变的,所以用另外一个数存储date,date = date * 10 + x % 10, x /= 10
2 . 把月和日都分出来。
20010101
日:date / 100
月:date % 10000 / 100
年:date / 10000
3 . 如果月份为0或大于12则不符合规则,pass。2月平年有28天,闰年有29天。不是2月不需要特判,2月需要特判是否问闰年。如果日大于该月的日或者为0,则pass。2月需要看是和28还是29比较。如果还是大于,则pass
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int date)
{
int year = date / 10000;
int month = date % 10000 / 100;
int day = date % 100;
if(month ==0 || month >12) return false; // 月份不满足
if(day == 0 || month != 2 && day > days[month]) return false;
if(month ==2) //特判二月份
{
int leap = year % 4==0&&year %100!=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<=9999;i++)
{
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(date)) res++;
}
cout<<res;
}
桃之夭夭,灼灼其华