问题描述
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在1960年1月1日至2059年12月31日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
输入格式
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
输出格式
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。多个日期按从早到晚排列。
样例输入
02/03/04
样例输出
2002-03-04
2004-02-03
2004-03-02
由于最近在备考蓝桥杯,上午集训队比赛,堪堪A掉了一道日期题,让我产生了训练这一专题的想法, 于是找到了这道题。
首先觉得思路不难但是复杂,考虑点如下:
1、要分三种情况输出
2、这三种情况中如果出现值相等的情况如何解决(如输入02/02/02)。
3、在不同年份和月份下天数的变化情况。
第一遍敲了大概一百行,提交。一个样例没过,
网搜后看到一位大神的代码,30多行就A掉了,于是学习,也做了一些改进。
对于考虑一:可以采用函数复用的方法,三合一,减少代码量。
对于考虑二:每次判定完将结果存储set容器中(有序且去重),最后直接输出容器值
对于考虑三:考虑用一个二维数组把月份和天数关联,这样就不需要进行复杂的判定。
还需要特别注意日期为负的情况,栽在这里没拿满分。
直接贴代码。
#include
#include
#include
#include
#include
using namespace std;
set<string>s;
int m[2][13] = {0,31,28,31,30,31,30,31,31,30,31,30,31,
0,31,29,31,30,31,30,31,31,30,31,30,31};
bool leap(int y) {
if((y%4==0 && y%100) || y%400==0) return true;
return false;
}
void check(int a, int b, int c) {
char c1[15];
if(a > 59 ) a+=1900;
else a+= 2000;
bool flag1 = false;
if(b<=12 && b>=1) {
if(b==1 || b==3 || b==5 || b==7 || b==8 || b==10 || b==12) {
if(c<=31 && c>=1) flag1 = true;
}
else if(b==2) { //二月
if(leap(a)) {
if(c<=29 && c>=1) flag1 = true; //闰年
}
else {
if(c<=28 && c>=1) flag1 = true;
}
}
else if(b==4 || b==6 || b==9 || b==11) { //30天的月份
if(c<=30 && c>=1) flag1 = true;
}
}
if(flag1) {
sprintf(c1,"%d-%02d-%02d",a,b,c);
s.insert(c1);
}
}
int main() {
int a, b, c;
scanf("%d/%d/%d", &a, &b, &c);
check(a, b, c);
check(c, a, b);
check(c, b, a);
for(set<string>::iterator it=s.begin(); it != s.end(); it++) cout << *it << endl;
return 0;
}
可以看到,这段代码即使做了函数复用,采用了set容器存储,但没有把月份和天数关联在一个数组里,而是用if-else做多重判断,因此显著的增加了代码量。
#include
using namespace std;
//当既需要判断月份又需要判断月份下的天数时,可以用数组关联。
int m[2][13] = {0,31,28,31,30,31,30,31,31,30,31,30,31,
0,31,29,31,30,31,30,31,31,30,31,30,31};
set<string>e;
bool leap(int y) {
if((y%4==0 && y%100) || y%400==0) return true; //y%100简化
return false;
}
void check(int a, int b, int c) {
char c1[15];
if(a>59) a+=1900;
else a+=2000;
int f = 0;
if(leap(a)) f=1;
if(b>=1 && b<=12)
if(c>=1 && c<=m[f][b]) {
sprintf(c1, "%d-%02d-%02d", a, b, c); //打印
e.insert(c1);
}
}
int main() {
int a, b, c; scanf("%02d/%02d/%02d", &a, &b, &c);
check(a,b,c); check(c,a,b); check(c,b,a);
for(set<string>::iterator it=e.begin(); it!=e.end(); it++) cout << *it << endl;
return 0;}
如果这篇文章对你产生了帮助,就请给博主一个赞吧!大家的点赞是我创作的最大动力!