日期问题的痛点:各种各样的判断条件,看似简单,但是容易出错,看不到输入的样例就容易找不到问题所在。
我的思路:先枚举出所有可能的日期,再判断他们是否合法。
注意!题目中说明了要按照从早到晚输出。而且会出现日期重复的情况。比如$02/02/02$,此时不加上判断,会输出三个重复的日期。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
bool mem[20600000];//判断是不是已经输出过的日期
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int leapyear(int y)
{
if(y%400==0 || (y%100 && y%4==0))
{
return 1;
}
else return 0;
}
bool judge(int date)
{
int y=date/10000,m=(date/100)%100,d=date%100;
if(m<1 || m>12)return false;
if(m!=2 && (d>month[m]|| d<1))return false;
if(m==2 && (d>month[m]+leapyear(y) || d<1))return false;
else if(y<1960 || y>2059)return false;
return true;
}
string n;
int main()
{
cin>>n;
int d1=(n[0]-'0')*10+n[1]-'0',d2=(n[3]-'0')*10+n[4]-'0',d3=(n[6]-'0')*10+n[7]-'0';
//第一步,确定可能的日期。
int date[7]={};
date[1]=(d1+1900)*10000+d2*100+d3,date[2]=(d1+2000)*10000+d2*100+d3;
date[3]=(d3+1900)*10000+d1*100+d2,date[4]=(d3+2000)*10000+d1*100+d2;
date[5]=(d3+1900)*10000+d2*100+d1,date[6]=(d3+2000)*10000+d2*100+d1;
//第二步,进行筛选。
sort(date+1,date+7);//排序
for (int i = 1; i <= 6; i ++ )
{
if(judge(date[i]) && !mem[date[i]])
{
int y=date[i]/10000,m=(date[i]/100)%100,d=date[i]%100;
printf("%d-",y);
if(m<10)printf("0%d-",m);
else printf("%d-",m);
if(d<10)printf("0%d",d);
else printf("%d",d);
puts("");
mem[date[i]]=1;
}
}
return 0;
}