题目
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 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
分析
枚举
代码解释
isLeapYear
函数:用于判断给定的年份是否为闰年。闰年的判断规则是:能被 4 整除但不能被 100 整除,或者能被 400 整除。
isValidDate
函数:用于判断给定的年、月、日组合是否为合法日期。首先检查年份是否在 1960 年到 2059 年之间,然后检查月份是否在 1 到 12 之间,最后根据月份和是否为闰年确定该月的天数,并检查日期是否在该范围内。
generateDateStr
函数:将年、月、日组合成 yyyy-MM-dd
格式的字符串。如果月份或日期小于 10,则在前面补 0。
processDate
函数:
- 解析输入的日期字符串,提取出
a
、b
、c
三个数字。 - 分别考虑年 / 月 / 日、月 / 日 / 年、日 / 月 / 年三种日期格式,对于每种格式,尝试将年份加上 1900 和 2000,然后调用
isValidDate
函数判断是否为合法日期,如果是,则将其转换为字符串并添加到dates
向量中。 - 对
dates
向量进行排序并去重。
main
函数:读取输入的日期字符串,调用 processDate
函数处理该日期,然后输出所有可能的日期。
时间复杂度:O(1)
空间复杂度:O(1)
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
// 判断是否为闰年
bool isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
// 判断日期是否合法
bool isValidDate(int year, int month, int day) {
if (year < 1960 || year > 2059) return false;
if (month < 1 || month > 12) return false;
int daysInMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (isLeapYear(year)) daysInMonth[2] = 29;
return day >= 1 && day <= daysInMonth[month];
}
// 生成日期字符串
std::string generateDateStr(int year, int month, int day) {
std::ostringstream oss;
oss << year << "-";
if (month < 10) oss << "0";
oss << month << "-";
if (day < 10) oss << "0";
oss << day;
return oss.str();
}
// 处理输入日期
std::vector<std::string> processDate(const std::string& input) {
int a, b, c;
sscanf(input.c_str(), "%d/%d/%d", &a, &b, &c);
std::vector<std::string> dates;
std::vector<int> years = {1900 + a, 2000 + a};
std::vector<int> months = {b};
std::vector<int> days = {c};
// 年/月/日
for (int year : years) {
if (isValidDate(year, b, c)) {
dates.push_back(generateDateStr(year, b, c));
}
}
// 月/日/年
for (int year : {1900 + c, 2000 + c}) {
if (isValidDate(year, a, b)) {
dates.push_back(generateDateStr(year, a, b));
}
}
// 日/月/年
for (int year : {1900 + c, 2000 + c}) {
if (isValidDate(year, b, a)) {
dates.push_back(generateDateStr(year, b, a));
}
}
// 去重并排序
std::sort(dates.begin(), dates.end());
dates.erase(std::unique(dates.begin(), dates.end()), dates.end());
return dates;
}
int main() {
std::string input;
std::cin >> input;
std::vector<std::string> dates = processDate(input);
for (const auto& date : dates) {
std::cout << date << std::endl;
}
return 0;
}