蓝桥杯省赛训练营——日期的计算

日期的计算

经常会遇到别人问你几月几号是星期几的情况,如何不查日历,直接用程序算出来呢?一种最简单的方法是,记住很久以前的某一天是星期几,比如公元 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 月计算,上述的除法均为整除

蒜头君的生日

蒜头君的生日快到了,蒜头君希望是在周末,蒜头君请你帮忙算出他生日在星期几。

蓝桥杯省赛训练营——日期的计算_第1张图片

代码

#include 
#include 
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)天纪念日。

蓝桥杯省赛训练营——日期的计算_第2张图片

代码

#include 
#include
#include
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

接下来 4 行,每行输入两个整数,m,d, 分别表示春节、清明节、端午节和中秋节的阳历日期。

最后一行一个整数表示当年 1 月 1 号是星期几(一周内的第几天,每周从星期一开始计数,即星期一为第一天)。

输出格式

输出一个整数,表示当年放假的天数。

样例输入

2017
1 28
4 4
5 30
10 4
7

样例输出

113

解题思路

定义一个数组days[],里面的每个元素表示这一年中的每一天,初始时全部元素为0。
对数组进行遍历,先把阴历,阳历节日的日子进行置1。
再将所有的周六周日置1。
最后对days数组求和输出即可。

代码

#include 
#include
#include
#include
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;
}

你可能感兴趣的:(蓝桥杯C++训练系统)