小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在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
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
思路:
1,对于题目的输入AA/BB/CC,有三种可能情况;
年/月/日 ————AA/BB/CC
月/日/年 ————CC/AA/BB
日/月/年————CC/BB/AA
2,分别对这三种情况的年月日的范围,进行判定;
3,排序后,输出结果。
参考代码:(使用vector<int>存储,sort排序)
using namespace std;
int monthNum[13][2] ={{0,0},{31,31}, {28,29}, {31,31},{30,30},{31,31},{30,30},
{31,31},{31,31},{30,30},{31,31},{30,30},{31,31}};//日期打表
bool isLeap(int y){//判断是否是闰年
return y % 400 == 0 || (y % 4 == 0 && y % 100 == 0);
}
bool isYear(int x){//判断是2000前,还是20年后
if(x >= 60) return true;//如果是1960~1999之间
else return false;//如果是2000~2059年之间
}
bool isMonth(int x){//判断月份是否在1~12之间
if(x > 0 && x< 13) return true;
else return false;
}
bool isDay(int year, int month, int day){//判断日期是否正确
if(day <= monthNum[month][isLeap(year)] && day > 0)//判断日期是否是闰年,且对应月份的天数在1~合理的上限制
return true;
else
return false;
}
struct Date{//存贮日期
int y;
int m;
int d;
Date(int _y, int _m, int _d): y(_y), m(_m), d(_d){}
};
vector<Date> v;
void judge(int x, int y , int z){
int year = 0;
if(isMonth(y)){//年、月、日判断
if(isYear(x)){
year = 1900 + x;
if(isDay(year, y,z)){
// date[k].y = year;
// date[k].m = y;
// date[k].d = z;
v.push_back(Date(year, y, z));//动态数组存储日期
}
}else{
year = 2000 + x;
if(isDay(year, y,z)){
// date[k].y = year;
// date[k].m = y;
// date[k].d = z;
v.push_back(Date(year, y, z));
}
}
}
}
bool cmp(const Date &a, const Date &b){
if(a.y != b.y){
if(a.y >= 60 && b.y >= 60){
return a.y < b.y;
}else{
if(a.y >= 60 && b.y < 60) return a.y > b.y;
else return a.y < b.y;
}
}else if(a.m != b.m){
return a.m < b.m;
}else{
return a.d < b.d;
}
}
int main(){
int AA,BB,CC;
scanf("%d/%d/%d", &AA, &BB, &CC);
judge(AA,BB,CC);
judge(CC,AA,BB);
judge(CC,BB,AA);
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < v.size(); ++i) {
if(!i){
printf("%d-%02d-%02d\n", v[i].y, v[i].m, v[i].d);
}else{//去重复
if((v[i].y == v[i -1].y && v[i].m == v[i - 1].m && v[i].d == v[i - 1].d)){
continue;
}else{
printf("%d-%02d-%02d\n", v[i].y, v[i].m, v[i].d);
}
}
}
return 0;
}
参考代码2:(使用set<string> 存储)
using namespace std;
bool isLeap(int year){//判断是否是闰年
return year % 400 == 0 || (year %4 == 0 && year % 100 !=0);
}
void i2s(int i, string &s){//把数字转为字符串
stringstream stream;
stream << i;
stream >> s;
}
string f(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 "";//这里处理已经包含了对天数上限为31的月份处理
bool _isLeap = isLeap(a);//判断是否是闰年
switch(b){//对日期上限为30或者2月的月份进行处理
case 2:
if(_isLeap && c > 29) return "";
if(!_isLeap && c > 28) return "";
break;
case 4:
if(c > 30) return "";
case 6:
if(c > 30) return "";
case 9:
if(c > 30) return "";
case 11:
if(c > 30) return "";
default:
break;
}
string _a, _b, _c;
i2s(a, _a);//数字转为字符串
i2s(b, _b);
i2s(c, _c);
if(_b.length() == 1) _b = "0" + _b;//对于只有1位的进行加0操作
if(_c.length() == 1) _c = "0" + _c;
return _a + "-" + _b + "-" + _c;//拼接成一个日期
}
int main(){
string in;
cin >> in;
int a = 0, b = 0, c = 0;
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 = f(a, b, c);
string case2 = f(c, a, b);
string case3 = f(c, b, a);
set<string> ans;//填入set自动排序去重复
if(case1 != "") ans.insert(case1);
if(case2 != "") ans.insert(case2);
if(case3 != "") ans.insert(case3);
for (set<string>::iterator it = ans.begin(); it != ans.end() ; ++it) {//使用迭代器进行输出
cout << *it << endl;
}
return 0;
}