日期模拟几乎是蓝桥杯每年的必考题目,所以总结一下往年题目
小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在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
#include<bits/stdc++.h> using namespace std; int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; bool cheak(int yy, int mm, int dd) { if (mm == 0 || mm > 12) return false; if (dd == 0) return false; if (mm == 2) { int leap = (yy % 4 == 0 && yy % 100) || (yy % 400 == 0); if (dd > days[mm] + leap) return false; } else { if (dd > days[mm]) return false; } return true; } int main() { int a, b, c; scanf("%d/%d/%d", &a, &b, &c); for (int i = 19600101; i <= 20591231; i ++) { int yy = i / 10000, mm = i % 10000 / 100, dd = i % 100; if (cheak(yy, mm, dd)) { if (yy%100 == a && mm == b && dd == c) { printf("%d-%02d-%02d\n", yy, mm, dd); } else if (yy%100 == c && mm == a && dd == b) { printf("%d-%02d-%02d\n", yy, mm, dd); } else if (yy%100 == c && mm == b && dd == a) { printf("%d-%02d-%02d\n", yy, mm, dd); } } } return 0; }
2020年春节期间,有一个特殊的日期引起了大家的注意:2020年2月2日。因为如果将这个日期按
yyyymmdd
的格式写成一个8位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。有人表示 20200202 是“千年一遇”的特殊日子。对此小明很不认同,因为不到2年之后就是下一个回文日期:20211202 即2021年12月2日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即2121年12月12日。算不上“千年一遇”,顶多算“千年两遇”。
给定一个8位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
输入包含一个八位整数 N,表示日期。
输出两行,每行1个八位数。
第一行表示下一个回文日期,第二行表示下一个ABABBABA型的回文日期。
20200202
样例输出
20211202
21211212
#include<bits/stdc++.h> using namespace std; int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool check (int yy, int mm, int dd) { if (!dd) return false; if (!mm || mm > 12) return false; int leap = (yy % 4 == 0 || yy % 100) || (yy % 400 == 0); if (mm == 2) { if (dd > day[mm] + leap) return false; } else { if (dd > day[mm]) return false; } return true; } bool huiwen(string s) { for (int i = 0, j = s.size()-1; i < j; i ++, j --) { if (s[i] != s[j]) return false; } return true; } bool ty(string s) { if (s[0] == s[1]) return false; char a = s[0], b = s[1]; for (int i = 0; i < s.size(); i ++) { if (s[i] == a) s[i] = 'A'; if (s[i] == b) s[i] = 'B'; } if (s == "ABABBABA") return true; else return false; } int main() { int n; cin >> n; int flag = 0; for (int i = n + 1; ; i ++) { int yy = i / 10000, mm = i % 10000 / 100, dd = i % 100; if (check(yy, mm, dd)) { string s; int k = i; while (k) { int x = k % 10; s += x+'0'; k /= 10; } if (huiwen(s) && !flag) { cout << s << endl; flag = 1; } if (ty(s)) { cout << s; break; } } } return 0; }
通过上面两道题可以看出一个大致的套路都是通过暴力遍历每一个整数然后判断这个整数是否是一个正确的日期,总结为以下模板
int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool check (int yy, int mm, int dd) { if (!dd) return false; if (!mm || mm > 12) return false; int leap = (yy % 4 == 0 || yy % 100) || (yy % 400 == 0); if (mm == 2) { if (dd > day[mm] + leap) return false; } else { if (dd > day[mm]) return false; } return true; }