P8651 [蓝桥杯 2017 省 B] 日期问题 题解
CleverRaccoon · · 题解
分析
本题的年份已经给定了范围,所以直接枚举即可,不会超时。
思路
使用三重循环,第一层循环枚举年份,第二层循环枚举月份,第三层循环枚举天数。
可以使用一个数组来记录每个月的天数,不用逐个月来判断。
口诀:一三五七八十腊,三十一天永不差,四六九冬三十日,平年二月二十八,闰年二月把一加。
那么如何判断一个年份是否是闰年呢?一个年份是闰年,当且仅当它满足以下两种条件之一:
-
年份是
4 的倍数但不是100 的倍数。 -
年份是
400 的倍数。
判断闰年的代码很简单,只需要进行基本逻辑上面的判断即可:
inline bool isLeapYear(int y) {
return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
}
题目中说,格式有三种可能,所以我们要判断这三种情况。
- 『年月日』的格式:
a == year % 100 && b == month && c == day
- 『月日年』的格式:
a == month && b == day && c == year % 100
- 『日月年』的格式:
a == day && b == month && c == year % 100
注意,由于输入的年份只有两位,判断时要把枚举出来的年份对
输出格式也要非常注意:月和日前要补零!
printf("%d-%02d-%02d\n", year, month, day);
代码
#include <bits/stdc++.h>
using namespace std;
const int StartYear = 1960, EndYear = 2059;
/*
一三五七八十腊,
三十一天永不差,
四六九冬三十日,
平年二月二十八,
闰年二月把一加。
*/
int daysOfMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 判断是否为闰年
inline bool isLeapYear(int y) {
return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
}
int main() {
int a, b, c;
scanf("%d/%d/%d", &a, &b, &c);
for(int year = StartYear; year <= EndYear; ++year) { // 1960年到2059年
daysOfMonth[2] = (isLeapYear(year) ? 29 : 28); // 根据是否是闰年来修改二月的天数
for(int month = 1; month <= 12; ++month)
for(int day = 1; day <= daysOfMonth[month]; ++day)
if((a == year % 100 && b == month && c == day) ||
(a == month && b == day && c == year % 100) ||
(a == day && b == month && c == year % 100)) // 判断是否符合条件
printf("%d-%02d-%02d\n", year, month, day); // 注意输出的格式
}
return 0;
}
题解结束了,有什么问题欢迎私信交流,谢谢大家!