欢迎大家来到zz菜鸟的博客,近期我在备战蓝桥杯,会发布一些我对部分题目的看法。希望大家能够多多支持。
题目描述
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 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
思路分析
- 数据类型的转换: 首先注意到这里输入和输出格式都是字符串,而在把输入的字符串中给出的数字信息转化成整数型提起出来,最后输出的时候在转化成字符串型。
- 日期的处理:由于闰年和平年二月份天数不同,需要对二月单独处理,而要对日期是否规范进行检验。
- 多个日期排序:由于要多多个日期进行排序且不能重复,故需要用到set容器。
代码
#include<iostream>
#include<sstream>
#include<set>
using namespace std;
bool isleap(int& year) //判断是否为闰年
{
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}
void i2s(int a, string& y) //整数转字符串
{
stringstream ss;
ss << a;
ss>>y;
}
string ff(int a, int b, int c) //检验日期是否规范并返回输出结果之一
{
if (a >= 0 && a <= 59)a += 2000;
else if (a >= 60 && a <= 99)a += 1900;
else return"";
if (b < 1 || b>12)return"";
if (c < 1 || c>31)return"";
bool leap = isleap(a);
switch (b) {
case 2:
if (leap && c > 29) return"";
if (!leap && c > 28) return"";
break;
case 4:
if (c > 30) return"";
break;
case 6:
if (c > 30) return"";
break;
case 9:
if (c > 30) return"";
break;
case 11:
if (c > 30) return"";
break;
}
string y, m, d;
i2s(a, y);
i2s(b, m);
i2s(c, d);
if (m.length() == 1) m = '0' + m;
if (d.length() == 1) d = '0' + d;
return y + '-' + m + '-' + d;
}
int main()
{
string in;
cin >> in;
int a, b, c;
// 将字符转化成整数形式
a = (in[0] - '0') * 10 + (in[1] - '0');
b = (in[3] - '0') * 10 + (in[4] - '0');
c = (in[6] - '0') * 10 + (in[7] - '0');
//得到三种不同的字符串日期
string case1=ff(a,b,c);
string case2=ff(c,b,a);
string case3=ff(c,a,b);
//使用set容器进行排序和去重
set<string>ans;
if(case1!="")ans.insert(case1);
if(case2!="")ans.insert(case2);
if(case3!="")ans.insert(case3);
for (set<string>::iterator iter = ans.begin(); iter != ans.end(); iter++) {
cout << *iter << endl;
}
return 0;
}