题目
日历有 阳历(公历) 和 阴历(农历) 之分。每年都有法定节假日,这些分成三类——双休、阳历节假日、阴历节假日。
双休
- 周六和周日 22 天
阳历节假日
- 元旦:阳历每年 1 月 1 日,放假 11 天
- 劳动节:阳历每年 5 月 1 日,放假 11天
- 国庆节:阳历每年 10 月 1 日,放假 33天
- 圣诞节:阳历每年 12 月 25 日,放假 11 天
阴历节假日
- 春节:阴历每年 1 月 1 日,放假 33 天
- 清明节:阳历每年 4 月 4 - 6 日之间的某天,放假 11 天
- 端午节:阴历每年 5 月 5 日,放假 11天
- 中秋节:阴历每年 8 月 15 日, 放假 11天
当节假日和双休重合时,双休 不延后 也 不提前,保证节假日之间不会重合。现在给你某年的所有阴历节假日的 阳历 日期,以及当年的 1 月 1 日是星期几,请你计算出这一年(阳历 1 月 1 日到 12 月 31 日)放了多少天假(包括双休、阳历节假日和阴历节假日)。
输入格式
第一行输入年份 y(1900<y≤2050)。接下来 44 行,每行输入两个整数 m,d, 依次表示春节、清明节、端午节和中秋节的阳历日期。最后一行一个整数表示当年 1 月 1 号是星期几(一周内的第几天,每周从星期一开始计数,即星期一为第一天)。
输出格式
输出一个整数,表示当年放假的天数。
样例输入
2017 1 28 4 4 5 30 10 4 7
样例输出
113
题目解析
关于日期,我们可以建立一个 day 数组,用于记录每个月有多少天,可以帮助我们遍历。(先不用着急 2 月份的天数不同的情况,我们可以在main中判断是否是闰年再去修改)
一三五七八十腊,三十一天永不差。
int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
下一步,我们处理二月闰年的问题。
年份能整除4或百年年份能整除400的是闰年。
根据这个规律,可以对二月的天数进行修改。
if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0){
day[2]++;
}
下一步,我们使用 mm 数组 和 dd 数组 来存储节假日的日期。
先输入阳历的节假日,因为是固定的,所以直接写进数组即可。
int mm[10] = {1, 5, 10, 10, 10, 12};
int dd[10] = {1, 1, 1, 2, 3, 25};
而阴历的节假日每年都可能发生变化的,因此需要用户输入,我们将输入写进数组即可。
但这里需要注意一下,春节因为有三天,所以我们单独拎出来处理。使用 变量f 记录春节所剩天数,当 f = 0 的时候说明春节记录完成。
判断完春节后,我们需要计算周末,计算周末直接使用 变量w 来记录星期几。当 w = 8 的时候置为 1 即可。
排除周末以后,最后来判断剩下的节假日,这很好办了,直接匹配即可。
注意:计数是一个循环的过程,每次循环结束需要到下一天,这时候就需要一个 nextday 函数帮我们对日期进行修改。
整个计数的循环如下:
while(m != 13){
//先判春节
if(m == mm[6] && d == dd[6]){
ans++;//是假期
f = 2;
}else if(f){
ans++;
f--;//春节少一天了
}else if(w == 6 || w == 7){
//周末
ans++;
}else{
for(int i = 0; i < 10; i++){
if(m == mm[i] && d == dd[i]){
ans++;
break;
}
}
}
nextday(m, d);
w = w + 1;
if(w == 8)
w = 1;
}
nextday 函数的参数是两个引用,来修改 月 和 日。
int nextday(int &m, int &d){
if(d == day[m]){
m++;
d = 1;
}else{
d++;
}
}
完整代码
#include<bits/stdc++.h>
using namespace std;
int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int mm[10] = {1, 5, 10, 10, 10, 12};
int dd[10] = {1, 1, 1, 2, 3, 25};
int nextday(int &m, int &d){
if(d == day[m]){
m++;
d = 1;
}else{
d++;
}
}
int main(){
int y, w, m, d, f, ans;
scanf("%d", &y);
if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0){
day[2]++;
}
for(int i = 6; i < 10; i++){
scanf("%d %d", &mm[i], &dd[i]);
}
scanf("%d", &w);
m = 1;
d = 1;
ans = 0;
f = 0;
while(m != 13){
//先判春节
if(m == mm[6] && d == dd[6]){
ans++;//是假期
f = 2;
}else if(f){
ans++;
f--;//春节少一天了
}else if(w == 6 || w == 7){
//周末
ans++;
}else{
for(int i = 0; i < 10; i++){
if(m == mm[i] && d == dd[i]){
ans++;
break;
}
}
}
nextday(m, d);
w = w + 1;
if(w == 8)
w = 1;
}
printf("%d", ans);
return 0;
}