头像

Cyan

四川成都

深度强化学习炼丹师

2017年第八届蓝桥杯省赛-G.日期问题

2017年第八届蓝桥杯省赛-G.日期问题

2022-03-07 · 57次阅读 · 原创 · 数据结构与算法

原题链接

题面

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。

更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03 月 02 日。

给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入描述

一个日期,格式是 “AA/BB/CC” (0A,B,C90\leq A, B, C \leq 9)。

输出描述

输出若干个不相同的日期,每个日期一行,格式是 “yyyy-MM-dd”。多个日期按从早到晚排列。

输入样例

02/03/04

输出样例

2002-03-04
2004-02-03
2004-03-02

思路

模拟,日期

题目说了输入的日期为 年/月/日月/日/年日/月/年 三种格式,则有三种情况需要考虑:

  • 年/月/日:则读入时 a = 年b = 月c = 日,则按照(a, b, c)生成日期即可。
  • 月/日/年:则读入时 a = 月b = 日c = 年,则按照(c, a, b)生成日期即可。
  • 日/月/年:则读入时 a = 日b = 月c = 年,则按照(c, b, a)生成日期即可。

注意,题目要求多个的话从小到大输出,且可能存在几种格式相同的情况,则可以用set去重排序,再遍历输出set内的元素即可。

代码

#include<bits/stdc++.h> using namespace std; //每个月份的天数 int ds[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; //闰年判断 bool leap_year(int y) { return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0; } string get(int y, int m, int d) { //判断是上世纪还是本世纪,补全年份数据 if (y >= 0 && y <= 59) y += 2000; else y += 1900; //年份和月份超出范围,则返回空字符串 if (m < 1 || m > 12) return ""; int maxday = ds[m]; if (m == 2 && leap_year(y)) maxday++; if (d < 1 || d > maxday) return ""; //将年月日按给定格式返回 char a[20]; sprintf(a, "%04d-%02d-%02d", y, m, d); return string(a); } int main() { int a, b, c; scanf("%02d/%02d/%02d", &a, &b, &c); set<string> st; string t = get(a, b, c); //以yy/mm/dd格式读入时,则就为年月日对应a, b, c if (t.length()) st.insert(t); t = get(c, a, b); //以mm/dd/yy格式读入时,则就为年月日对应c, a, b if (t.length()) st.insert(t); t = get(c, b, a); //以dd/mm/uyy格式读入时,则就为年月日对应c, b, a if (t.length()) st.insert(t); for (auto &s:st) cout << s << endl; return 0; }

标题: 2017年第八届蓝桥杯省赛-G.日期问题
链接: https://www.fightingok.cn/detail/198
更新: 2022-09-18 22:47:29
版权: 本文采用 CC BY-NC-SA 3.0 CN 协议进行许可