蓝桥杯日期类模板(超详解)【沈七】

蓝桥杯日期类模板

  • 前言
  • 制造日期回文数
  • 判断日期是否合法
  • 判断某年月份的天数
  • 计算某两天的相隔天数
    • 代码做法
      • 计算器妙用
  • 某两天内星期一的个数
    • 代码做法
    • Excel妙用
  • 给定年月日求n天后对应的日期
  • 历年真题
    • 高斯日记
    • 日期问题
    • 黑色星期五
  • 完结散花
  • 参考文献

前言

唤我沈七就好啦。

日期类问题可以说是蓝桥杯当中的常客了,
我整理了一下历年真题,归纳出了其中的模板。
希望对你有所帮助。

制造日期回文数

#include
using namespace std;
int sum;
int m[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};//枚举月份
int main()
{
    int a,b,x;
    cin>>a>>b;
    for (int i = 1; i <13; i ++ )//月
    for(int j=1;j<=m[i];j++)//日
   {
       //月份和日期确定下来之后,回文日期的年份也就确定下来了
       x=(j%10*1000+j/10*100+i%10*10+i/10)*10000+i*100+j;
       if(x>=a&&x<=b)//判断是否在给定区间内
       sum++;
   }
   cout<<sum;
    return  0;
}

判断日期是否合法

int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int y ,int m , int d)
{
	if(!d||!m||m>12)return 0;
	if(m!=2)
	{
		if(d>day[m])
        return 0;
	}
	else
	{
		int idx=((y % 100!=0 && y % 4==0)||(y%400==0));
		if(d>day[2]+idx)return 0;
	}
	return 1;
}

判断某年月份的天数

int moth[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y, int m)
{
	int leap = y%4==0&&y%100!=0||y%400==0;
	if(m!=2)
	return moth[m];
	return 28+leap; 
}

计算某两天的相隔天数

代码做法

#include
using namespace std;
int moth[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y, int m)
{
	int leap = y%4==0&&y%100!=0||y%400==0;
	if(m!=2)
	return moth[m];
	return 28+leap; 
}
int main()
{
	int ans=0;
	int y,m,d;
	int y1,m1,d1;
	cin>>y>>m>>d;
	cin>>y1>>m1>>d1; 
	while(1)
	{
		ans++,d++;
		if(d>get(y,m))
		m++,d=1;
		if(m>12)
		y++,m=1;
		if(y==y1&&m==m1&&d==d1)
		{
			cout<<ans;
			return 0;
		}
	}
	return 0;
}

计算器妙用

蓝桥杯日期类模板(超详解)【沈七】_第1张图片

某两天内星期一的个数

代码做法

1.先计算出两日期的相隔天数

2.由当天的日期星期反推给定日期的星期

(day 1 = day 2 - 相隔天数 % 7 )

3.根据给定日期的星期与所取星期的关系,判断答案与 相隔天数 / 7 是否差 1

Excel妙用

注:Excel 只能计算1900年后的时间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RJQgBEJF-1647358366406)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220314235033268.png)]

蓝桥杯日期类模板(超详解)【沈七】_第2张图片蓝桥杯日期类模板(超详解)【沈七】_第3张图片

给定年月日求n天后对应的日期

#include
using namespace std;
int moth[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y, int m)
{
	int leap = y%4==0&&y%100!=0||y%400==0;
	if(m!=2)
	return moth[m];
	return 28+leap; 
}
int main()
{
	int y,m,d,n;
	cin>>y>>m>>d>>n;
	while(n--)
	{
		d++;
		if(d>get(y,m))
		m++,d=1;
		if(m>12)
		y++,m=1;
	}
	printf("%d年%d月%d日",y,m,d);
	return 0;
}

历年真题

高斯日记

第四届蓝桥杯C++组

大数学家高斯有个好习惯:无论如何都要记日记。

他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210

后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?

高斯出生于:1777年4月30日。

在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。

高斯获得博士学位的那天日记上标着:8113

请你算出高斯获得博士学位的年月日。

坑点

这题不能用Excel,不符合适用范围

根据上面模板算出时间后需要 - 1!!!

这计算的是相隔的天数 需要减去 1777年4月30日,他出生的那一天!!

#include
using namespace std;
int moth[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y, int m)
{
	int leap = y%4==0&&y%100!=0||y%400==0;
	if(m!=2)
	return moth[m];
	return 28+leap; 
}
int main()
{
	int y,m,d,n;
	cin>>y>>m>>d>>n;
	while(n--)
	{
		d++;
		if(d>get(y,m))
		m++,d=1;
		if(m>12)
		y++,m=1;
	}
	printf("%d年%d月%d日",y,m,d-1);
    //一定要 - 1!!!,因为这计算出来的是相隔的天数 需要减去 1777年4月30日,他出生的那一天!!
	return 0;
}

日期问题

第八届蓝桥杯省赛C++组

小明正在整理一批历史文献。这些历史文献中出现了很多日期。

小明知道这些日期都在1960年1月1日至2059年12月31日。

令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。

更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。

给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

【 输入格式】

一个日期,格式是”AA/BB/CC”。

即每个’/’隔开的部分由两个 0-9 之间的数字(不一定相同)组成。

【输出格式】

输出若干个不相同的日期,每个日期一行,格式是”yyyy-MM-dd”。

多个日期按从早到晚排列。

【 数据范围】

0≤A,B,C≤9

【输入样例】:

02/03/04

【输出样例】:

2002-03-04
2004-02-03
2004-03-02
#include
using namespace std;
int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int y ,int m , int d)
{
	if(!d||!m||m>12)return 0;
	if(m!=2)
	{
		if(d>day[m])return 0;
	}
	else
	{
		int idx=((y % 100!=0 && y % 4==0)||(y%400==0));
		if(d>day[2]+idx)return 0;
	}
	return 1;
}
int main()
{
	int a,b,c;
	scanf("%d/%d/%d",&a,&b,&c);
	for(int i = 19600101 ; i <= 20591231 ; i ++)
	{
		int y=i/10000,m=i%1000/100,d=i%100;
		if(check(y,m,d))
		{
			if((y%100==a&&m==b&&d==c)|| //年月日
			   (y%100==c&&m==a&&d==b)|| //
			   (y%100==c&&m==b&&d==a))  
			printf("%d-%02d-%02d\n",y,m,d);//补前导
		}
	}
	return 0;
}

黑色星期五

第一届蓝桥杯C/C++组

13号又是一个星期五。13号在星期五比在其他日子少吗?为了回答这个问题,请你写一个程序计算每个月的十三号落在周一到周日的次数。

给出N年的一个周期,要求计算1900年1月1日至1900+N-1年12月31日中十三号落在周一到周日的次数,N为正整数且不大于400。

这里有一些你要知道的:
  1、1900年1月1日是星期一。
  2、4,6,11和9月有30天。其他月份除了2月都有31天。闰年2月有29天,平年2月有28天。
  3、年份可以被4整除的为闰年(1992年是闰年,但是1990年不是闰年)。
  4、以上规则不适合于世纪年。可以被400整除的世纪年为闰年,否则为平年。所以,1700,1800,1900和2100年是平年,而2000年是闰年。

【输入格式】

一个正整数:N。

【输出格式】

七个在一行且相分开的整数,它们代表13日是星期六、星期日、星期一、…、星期五的次数。

【输入样例】

20

【输出样例】

36 33 34 33 35 35 34
#include
using namespace std;
long long ans=1,cnt[100];
int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int  get(int y,int m)
{
	if(m!=2)
	return moth[m];
	int leap=y%4==0&&y%100!=0||y%400==0;
	return 28+leap;
}
int main()
{
	int n;
	cin>>n;n=n+1900-1;
	int y=1900,m=1,d=1;
	while(1)
	{
		d++;
		ans++;
		int day = ans%7;
		if(d>get(y,m))	
		m++,d=1;
		if(m>12)
		y++,m=1;
		if(d==13)
		cnt[day]++;
		if(y==n&&m==12&&d==31)
		{
			break;
		}
	}
	cout<<cnt[6]<<" "<<cnt[0]<<" ";//注意输出顺序,这是个坑
	for(int i = 1 ; i <= 5 ; i ++)
	cout<<cnt[i]<<" ";

	return 0;
}

完结散花

ok以上就是对 蓝桥杯日期类模板 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。

参考文献

https://www.acwing.com/activity/content/19/
https://blog.csdn.net/xiao_cangtian/article/details

你可能感兴趣的:(蓝桥杯攻略,蓝桥杯,算法,职场和发展)