日期问题

常见类型

日期问题是算法题中较为常见的一类题目,常见的题目类型有如下几类:
1、给出两个日期,求差值;
2、给出一个日期,问你是这年的第几天;
3、给出这天是某年的第几天,问你日期;
4、给出一个日期,问你是星期几。

解决思路

将所有日期转化为距离某个固定日期的日期差,之后再进行统一操作,思路和Unix时间戳类似。这里我们选择计算从当前日期到1年1月1日的日期差,c++的计算函数如下所示:

1
2
3
4
int mon[12]={0,31,59,90,120,151,181,212,243,273,304,334};
long long cal(int year,int month,int day){
return (year-1)*365+(year-1)/4-(year-1)/100+(year-1)/400+day-1+mon[month-1]+((year%100!=0&&year%4==0)||(year%400==0&&month>2));
}

(year-1)*365+(year-1)/4-(year-1)/100+(year-1)/400部分计算前面整年的天数,mon[month-1]计算前面整月的天数,((year%100!=0&&year%40)||(year%4000&&month>2))判断今年是否需要加闰年。

OJ题目

日期差值

题目链接:https://www.nowcoder.com/questionTerminal/ccb7383c76fc48d2bbc27a2a6319631c

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <bits/stdc++.h>
using namespace std;
int mon[12]={0,31,59,90,120,151,181,212,243,273,304,334};//字典
int cal(int y,int m,int d)//给出年月日,计算距离1年1月1日的天数和
{
return (y-1)*365+(y-1)/4-(y-1)/100+(y-1)/400+mon[m-1]+d-1+(y%100!=0&&y%4==0||y%400==0&&m>2);
}
int main()
{
int x[2],year,month,day;
while(scanf("%4d%2d%2d",&year,&month,&day)!=EOF){
x[0]=cal(year,month,day);
scanf("%4d%2d%2d",&year,&month,&day);
x[1]=cal(year,month,day);
cout<<abs(x[0]-x[1])+1<<endl;
}
}

day of week

题目链接:https://www.nowcoder.com/questionTerminal/a3417270d1c0421587a60b93cdacbca0

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <bits/stdc++.h>

using namespace std;
int mon[12]={0,31,59,90,120,151,181,212,243,273,304,334};//字典
string weeks[7]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"};

long long cal(int year,int month,int day){
return (year-1)*365+(year-1)/4-(year-1)/100+(year-1)/400+day-1+mon[month-1]+((year%100!=0&&year%4==0)||(year%400==0&&month>2));
}

unordered_map<string,int> monthMap;

int main() {
int preWeek=6;
long long preNumber=cal(2001,10,14);
monthMap["January"]=1;
monthMap["February"]=2;
monthMap["March"]=3;
monthMap["April"]=4;
monthMap["May"]=5;
monthMap["June"]=6;
monthMap["July"]=7;
monthMap["August"]=8;
monthMap["September"]=9;
monthMap["October"]=10;
monthMap["November"]=11;
monthMap["December"]=12;

int day,year;
string monthString;
while (cin>>day>>monthString>>year){
int month=monthMap[monthString];
long long theNumber=cal(year,month,day);
long long c=theNumber-preNumber;
c+=preWeek;
int week=(c%7+7)%7;
cout<<weeks[week]<<endl;
}
return 0;
}

参考资料

  1. https://blog.csdn.net/hongmeipopo73/article/details/79183903

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 协议 ,转载请注明出处!