日期计算
日期的计算不管在竞赛还是在实际应用中都是一个比较重要的方面。比较常识的知识就不再赘述了。
闰年是一类比较特殊的年份,闰年比平年(非闰年)在2月份多一天。关于闰年的判断,很多同学还不是很清楚,下面是闰年的详细定义:
- 年份非整百且能被4整除的为闰年。(如2004年就是闰年,2005年不是闰年)
- 年份能被400整除的是闰年。(如2000年是闰年,1900年不是闰年)
需要特别注意,能被100整除的年份,必须要被400整除才是闰年。
int is_leap_year(int year) { if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) return 1; else return 0; }
经常会遇到别人问你几月几号是星期几的情况,如何不查日历,直接用程序算出来呢?
一种最简单的方法是,记住很久以前的某一天是星期几,比如公元1年1月1日是星期一。然后一天一天模拟,算出日期是星期几。这种方法容易理解,但是实现起来代码可能比较长。
除此之外,有一个公式可以快速地根据日期计算这一天是星期几,这被称为蔡基姆拉尔森计算公式。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <algorithm> 6 using namespace std; 7 8 int main() 9 { 10 string week[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","sunday"}; 11 int y,m,d,w; 12 cin>>y>>m>>d; 13 if(m==1||m==2) y--,m+=12; 14 w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; 15 cout<<week[w]<<endl; 16 return 0; 17 }
恋爱纪念日
蒜头君和花椰妹谈恋爱啦。祝福他们吧。蒜头君想知道第他们的第 100 天,200 天 ... 纪念日。
输入格式
输入 4 个整数 y,m,d,k,表示他们在一起的日期,保证是一个 1900 年 1 月 1 日以后的日期,蒜头君想知道他们的 k(0≤k≤10000)天纪念日。
输出格式
按照yyyy-mm-dd的格式输出 k 天纪念日的日期。月份和天数必须各输出 2 位。保证最后答案年份不超过 4 位。
样例输入1
2016 10 1 100
样例输出1
2017-01-09
样例输入2
2017 1 1 10
样例输出2
2017-01-11
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <algorithm> 6 using namespace std; 7 8 int judge(int y) 9 { 10 if((!y%4&&y%100)||(y%400)) return 1; 11 else return 0; 12 } 13 14 int m_d[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 15 16 int main() 17 { 18 int y,m,d,k; 19 cin>>y>>m>>d>>k; 20 int num=0; 21 for(int i=1;i<m;i++) 22 { 23 num+=m_d[i]; 24 if(judge(y)&&i==2) num++; 25 } 26 num+=d; 27 int rnum=judge(y)? 366-num:365-num; 28 int yy=y,mm=m,dd=d; 29 if(k>rnum) 30 { 31 k-=rnum; 32 yy=y+1; mm=1; dd=0; 33 while(1) 34 { 35 if(judge(yy)&&k-366>=0) 36 { 37 yy++; k-=366; 38 } 39 else if(!judge(yy)&&k-365>=0) 40 { 41 yy++; k-=365; 42 } 43 else break; 44 } 45 } 46 while(k--) 47 { 48 if(mm==2&&judge(yy)) 49 { 50 dd++; 51 if(dd>m_d[mm]+1) 52 { 53 dd=1; 54 mm++; 55 } 56 } 57 else 58 { 59 dd++; 60 if(dd>m_d[mm]) 61 { 62 dd=1; 63 mm++; 64 } 65 } 66 } 67 printf("%04d-%02d-%02d\n",yy,mm,dd); 68 return 0; 69 }
节假日
题目:
日历有 阳历(公历) 和 阴历(农历) 之分。每年都有法定节假日,这些分成三类—双休、阳历节假日、阴历节假日。
双休
1)周六和周日 2 天
阳历节假日
1)元旦:阳历每年 1 月 1 日,放假 1 天
2)劳动节:阳历每年 5 月 1 日,放假 1 天
3)国庆节:阳历每年 10 月 1 日,放假 3 天
4)圣诞节:阳历每年 12 月 25 日,放假 1 天
阴历节假日
1)春节:阴历每年 1 月 1 日,放假 3 天
2)清明节:阳历每年 4 月 4 - 6 日之间的某天,放假 1 天
3)端午节:阴历每年 5 月 5 日,放假 1 天
4)中秋节:阴历每年 8 月 15 日, 放假 1 天
当节假日和双休重合时,双休 不延后 也 不提前,保证节假日之间不会重合。现在给你某年的所有阴历节假日的 阳历 日期,以及当年的 1 月 1 日是星期几,请你计算出这一年(阳历 1 月 1 日到 12 月 31 日)放了多少天假(包括双休、阳历节假日和阴历节假日)。
输入格式
第一行输入年份 y(1900<y≤2050)。
接下来 4 行,每行输入两个整数,m,d, 分别表示春节、清明节、端午节和中秋节的阳历日期。
最后一行一个整数表示当年 1 月 1 号是星期几(一周内的第几天,每周从星期一开始计数,即星期一为第一天)。
输出格式
输出一个整数,表示当年放假的天数。
样例输入
2017 1 28 4 4 5 30 10 4 7
样例输出
113
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <algorithm> 6 using namespace std; 7 8 int m_d[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 9 int fj[8][3]={{1,1,1},{5,1,1},{10,1,3},{12,25,1},{0,0,3},{0,0,1},{0,0,1},{0,0,1}}; 10 11 int is_leap_year(int y) 12 { 13 return ((!(y%4)&&y%100)||!(y%400))?1:0; 14 } 15 16 int judge(int m,int d) 17 { 18 for(int i=0;i<8;i++) 19 { 20 if(m==fj[i][0]&&d==fj[i][1]) 21 return fj[i][2]; 22 } 23 return 0; 24 } 25 26 int main() 27 { 28 int y,k; 29 scanf("%d",&y); 30 int m=1,d=1; 31 for(int i=4;i<8;i++) 32 scanf("%d %d",&fj[i][0],&fj[i][1]); 33 scanf("%d",&k); 34 int ans=0; 35 int sum=365; 36 if(is_leap_year(y)) 37 { 38 sum++;m_d[2]++; 39 } 40 while(sum--) 41 { 42 int t=judge(m,d); 43 if(t) 44 { 45 while(t--) 46 { 47 d++; ans++; k++; 48 if(d>m_d[m]) 49 { 50 d=1; m++; 51 } 52 if(k>7) k=1; 53 } 54 } 55 else 56 { 57 if(k==6||k==7) ans++; 58 d++; k++; 59 if(d>m_d[m]) 60 { 61 d=1; m++; 62 } 63 if(k>7) k=1; 64 } 65 } 66 printf("%d\n",ans); 67 return 0; 68 }
-