B - 日期计算
已知 2011 年 11 月 11 日是星期五,问 Y Y Y Y YYYY YYYY 年 M M MM MM 月 D D DD DD 日是星期几?注意考虑闰年的情况。尤其是逢百年不闰,逢 400 年闰的情况。
Input
输入只有一行 YYYY MM DD
Output
输出只有一行 W
input
2011 11 11
output
5
Note
1599
≤
Y
Y
Y
Y
≤
2999
1599 \le YYYY \le 2999
1599≤YYYY≤2999
1
≤
M
M
≤
12
1 \le MM \le 12
1≤MM≤12
1
≤
D
D
≤
31
1 \le DD \le 31
1≤DD≤31,且确保测试样例中 YYYY 年 MM 月 DD 日是一个合理日期
1 ≤ W ≤ 7 1 \le W \le 7 1≤W≤7,分别代表周一到周日
做题过程:
做完直接疯了……这种日期的题目太折磨人了,
&
&
\&\&
&& 写成
∣
∣
||
∣∣ 找了一晚上bug。
解题方法就是求出两个日期之间的天数差。尝试了几种求天数的方法,下面这种我觉得最简单,假设两个时间点为
a
a
a 和
b
b
b 并且
a
≤
b
a\le b
a≤b,记
a
a
a 那一年已经过去的天数为
A
A
A,
b
b
b 那一年还没过的天数为
B
B
B,
a
a
a 年到
b
b
b 年的总天数(包括
a
a
a 那年和
b
b
b 那年)为
s
u
m
sum
sum,所以 天数差
a
n
s
=
s
u
m
−
A
−
B
ans=sum-A-B
ans=sum−A−B 至于换成星期几,题目给出的日期在2011.11.11之前和在2011.11.11之后的计算方法是不一样的,简单的方法是记下一个周期
T
T
T ,模
7
7
7 之后直接作为下标输出
T
[
a
n
s
%
7
]
T[ans\%7]
T[ans%7]。
日
期
大
:
T
1
[
7
]
=
{
5
,
6
,
7
,
1
,
2
,
3
,
4
}
;
日期大: T_1[7] = \{5, 6, 7, 1, 2, 3, 4\};
日期大:T1[7]={5,6,7,1,2,3,4};
日
期
小
:
T
2
[
7
]
=
{
5
,
4
,
3
,
2
,
1
,
7
,
6
}
;
日期小:T2[7] = \{5, 4, 3, 2, 1, 7, 6\};
日期小:T2[7]={5,4,3,2,1,7,6};
Code:
#include <bits/stdc++.h>
#define IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
using namespace std;
typedef long long ll;
struct node
{
int Y, M, D;
node(int Y = 0, int M = 0, int D = 0) : Y(Y), M(M), D(D) {}
};
int mon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool judge(int y) //判断闰年
{
if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
return true;
else
return false;
}
int main()
{
IO;
node a, b(2011, 11, 11); //a小b大
cin >> a.Y >> a.M >> a.D;
bool flag = false;
if (a.Y > b.Y || (a.Y == b.Y && a.M > b.M) || (a.Y == b.Y && a.M == b.M && a.D > b.D))
{
flag = true;
swap(a, b);
}
int sum1 = 0, sum2 = 0;
for (int i = a.Y; i <= b.Y; i++)
{
sum1 += 365;
if (judge(i))
sum1++;
}
for (int i = 1; i < a.M; i++)
{
sum2 += mon[i];
if (i == 2 && judge(a.Y))
sum2++;
}
sum2 += a.D;
for (int i = b.M; i <= 12; i++)
{
sum2 += mon[i];
if (i == 2 && judge(b.Y))
sum2++;
}
sum2 -= b.D;
int ans = sum1 - sum2;
ans %= 7;
int T1[7] = {5, 6, 7, 1, 2, 3, 4};
int T2[7] = {5, 4, 3, 2, 1, 7, 6};
//这种方式比较好理解
if (flag) //flag是true表示输入的日期大
cout << T1[ans] << endl;
else
cout << T2[ans] << endl;
//下面这种方式也行
// if (flag)
// cout << (ans + 4) % 7 + 1 << endl;
// else
// cout << 7 - ((ans + 2) % 7) << endl;
return 0;
}