藍橋杯省賽訓練營——日期的計算

日期的計算

經常會遇到別人問你幾月幾號是星期幾的情況,如何不查日曆,直接用程序算出來呢?一種最簡單的方法是,記住很久以前的某一天是星期幾,比如公元 1 年 1 月 1 日是星期一。然後一天一天模擬,算出日期是星期幾。這種方法容易理解,但是實現起來代碼可能比較長。除此之外,有一個公式可以快速地根據日期計算這一天是星期幾,這被稱爲 蔡基姆拉爾森計算公式

假設星期爲 w, 年份爲 y, 月份爲 m, 日期爲 d:

w=(d+2×m+3×(m+1)/5+y+y/4−y/100+y/400)%7

然後把計算出來的 w 加上 1 就是真正的星期幾了。

注意每年的 1,2 月要當成上一年 13,14 月計算,上述的除法均爲整除

蒜頭君的生日

蒜頭君的生日快到了,蒜頭君希望是在週末,蒜頭君請你幫忙算出他生日在星期幾。

在這裏插入圖片描述

代碼

#include <iostream>
#include <string>
using namespace std;
string weekdays[7] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
int whatday(int y, int m, int d) 
{
    m == 1 && (m = 13, y -= 1);
    m == 2 && (m = 14, y -= 1);
    return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
}
int main() {
    int y, m, d;
    cin >> y >> m >> d;
    cout << weekdays[whatday(y, m, d)] << endl;
    return 0;
}

蒜頭君和花椰妹談戀愛啦

蒜頭君和花椰妹談戀愛啦。祝福他們吧。蒜頭君想知道第他們的第100天,200天…紀念日。

輸入格式

輸入格式 輸入 4 個整數 y,m,d,k表示他們在一起的日期,保證是一是一個 1900 年 1 月 1 日以後的日期,蒜頭君想知道他們的 k(0≤k≤10000)天紀念日。

在這裏插入圖片描述

代碼

#include <iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
//日期結構體
typedef struct
{
	int y;
	int m;
	int d;
}day;
int m[2][13] = {{0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}};
//判斷是否爲閏年
int isrunyear(int year)
{
	if(year %400 ==0 || (year%100!=0 && year%4 ==0))
		return 1;
	else
		return 0;
}
//獲取n天后的日期
day getDate(day p,int n)
{
	while(n)
	{
		//如果當月未滿,天數++
		if( p.d < m[isrunyear(p.y)][p.m])
		{
			p.d++;
		}
		//如果當月的天數滿了並且當月不是12月
		else if(p.m !=12 && p.d == m[isrunyear(p.y)][p.m])
		{
			p.d = 1;
			p.m++;
		}
		//如果是這一年的最後一天了
		else if(p.m == 12 && p.d == 31)
		{
			p.y++;
			p.m = 1;
			p.d = 1;
		}
		n--;//時間往前走了一天,n自減
	}
	return p;
}
int main()
{
	day p;
	int n;
	cin>>p.y>>p.m>>p.d>>n;
	p = getDate(p,n);
	cout<<p.y<<"-";
	p.m<10 && cout<<0;
	cout<<p.m<<"-";
	p.d<10 && cout<<0;
	cout<<p.d<<endl;
	return 0;
}

節假日

日曆有 陽曆(公曆) 和 陰曆(農曆) 之分。每年都有法定節假日,這些分成三類—雙休、陽曆節假日、陰曆節假日。

雙休

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

解題思路

定義一個數組days[],裏面的每個元素表示這一年中的每一天,初始時全部元素爲0。
對數組進行遍歷,先把陰曆,陽曆節日的日子進行置1。
再將所有的週六週日置1。
最後對days數組求和輸出即可。

代碼

#include <iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
int days[367];
//判斷是否爲閏年
int isrunnian(int n)
{
	if(n%400==0 || (n%100!=0 && n%4==0))
		return 1;
	else
		return 0;
}
//計算當年的總天數
int alldays(int n)
{
	if(isrunnian(n))
		return 366;
	else
		return 365;
}
//計算這一天在這一年中排第幾天
int getsnumday(int year,int m,int d)
{
	int mm[2][14] = {{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};
	int ret = 0;
	for(int i=1;i<=m-1;i++)
		ret += mm[isrunnian(year)][i];
	ret += d;
	return ret;
}
int main()
{
	int year;
	cin>>year;
	//輸入四個節日
	int x1,y1,x2,y2,x3,y3,x4,y4;
	cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
	int start;//第一天是周幾
	cin>>start;
	int n1,n2;
	switch(start)
	{
		case 1:n1=6;n2=7;break;//當年第一個週六週日爲6,7
		case 2:n1=5;n2=6;break;//當年第一個週六週日爲5,6
		case 3:n1=4;n2=5;break;//當年第一個週六週日爲4,5
		case 4:n1=3;n2=4;break;//當年第一個週六週日爲3,4
		case 5:n1=2;n2=3;break;//當年第一個週六週日爲2,3
		case 6:n1=1;n2=2;break;//當年第一個週六週日爲1,2
		case 7:n1=1;n2=7;break;//當年第一個週六週日爲1,7
	}
	//先把陽曆節日的days[]置爲1
	days[1] = 1;//元旦節1月1日
	days[getsnumday(year,5,1)] = 1;//勞動節,5月1日
	days[getsnumday(year,10,1)] = days[getsnumday(year,10,2)] = days[getsnumday(year,10,3)] = 1;//國慶節,放假3天
	days[getsnumday(year,12,25)] = 1;//聖誕節放假1天
	//陰曆節假日
	days[getsnumday(year,x1,y1)] = days[getsnumday(year,x1,y1+1)] = days[getsnumday(year,x1,y1+2)] = 1;//春節3天
	days[getsnumday(year,x2,y2)] = 1;//清明節放假1天
	days[getsnumday(year,x3,y3)] = 1;//端午節放假1天
	days[getsnumday(year,x4,y4)] = 1;//中秋節放假1天
	//週六週日
	for(int i=1;i<=alldays(year);i++)
		if(i%7 == n1%7 || i%7 == n2%7)
			days[i] = 1;
	//統計多少個房價日
	int sum =0;
	for(int i=1;i<=alldays(year);i++)
		sum += days[i];
	cout<<sum;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章