IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 蓝桥杯C/C++B组省赛日期类问题汇总 -> 正文阅读

[C++知识库]蓝桥杯C/C++B组省赛日期类问题汇总

蓝桥2017第八届省赛第七题 日期问题
在这里插入图片描述
在这里插入图片描述
思路:暴力枚举从1960年1月1日到2059年12月31日的所有合法日期,然后拆分出年月日,如果符合题目中的三种情况之一(年/月/日 月/日/年 日/月/年)的输出即可

#include<bits/stdc++.h>
using namespace std;
int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int check(int year, int month, int day) {
	if (month == 0 || month > 12) {
		return false;
	}
	if (month != 2) { //不是二月份的时候
		if (day > a[month] || day == 0)
			return false;
	}
	if (month == 2) { //是二月
		//判断是否是闰年
		if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
			a[month] = 29;
			if (day > a[month] || day == 0)
				return false;

		} else {
			a[month] = 28;
			if (day > a[month] || day == 0)
				return false;
		}
	}
	return true;
}
int main() {
	int a, b, c;
	scanf("%d/%d/%d", &a, &b, &c);
	for (int i = 19600101; i <= 20591231; i++) {
		int day = i % 100;
		int month = i / 100 % 100;
		int year = i / 10000;
		bool flag = check(year, month, day);
		if (flag) { //是合法日期
			int year1 = year % 100;
			if ((year1 == a && month == b && day == c) || (year1 == c && month == a && day == b) || (year1 == c && month == b && day == a)) {
				printf("%d-%02d-%02d\n", year, month, day);
			}
		}
	}
}

数字拆分出年月日

//例如n=20591231
int year=n/10000;
int month=n/100%100;
int day=n%100;

判断一个拆分出来的年月日是否合法
首先判断月,月份等于0或大于12都是合法的
其次再判断日,这里2月份要分平年与闰年判断,平年28天,闰年29天,其余直接判断即可,如果天数大于当前月份的天数,即为不合法

int check(int year, int month, int day) {
	if (month == 0 || month > 12) {
		return false;
	}
	if (month != 2) { //不是二月份的时候
		if (day > a[month] || day == 0)
			return false;
	}
	if (month == 2) { //是二月
		//判断是否是闰年
		if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
			a[month] = 29;
			if (day > a[month] || day == 0)
				return false;

		} else {
			a[month] = 28;
			if (day > a[month] || day == 0)
				return false;
		}
	}
	return true;
}

蓝桥杯2018第九届省赛第一题
在这里插入图片描述
思路:判断一下闰年还是平年,然后手算即可


#include<bits/stdc++.h>
using namespace std;
int main()
{
	int year=2020;
	if(year%400==0||(year%4==0&&year%100!=0))
	{
	cout<<"闰年"<<endl;
	}
	else
	{
		cout<<"平年"<<endl; 
	}
	cout<<31+29+31+30+4<<endl;
}
//125

蓝桥杯2019第十届省赛第七题 回文日期
在这里插入图片描述
在这里插入图片描述
错了4次,这要是真放在比赛的时候,就无了
思路:判断n之后的第一个回文日期和第一个ABABBABA型的回文日期,暴力枚举即可,一开始我想的是枚举n-89991231,然后去判断就好了,由于只有8位,直接可以把每一位存到一个数组里,这时候就可以直接去判断数组
回文:a[0] == a[7] && a[1] == a[6] && a[2] == a[5] && a[3] == a[4]
ABABBABA型回文:(a[0] == a[2]) && (a[2] == a[5]) && (a[5] == a[7]) && (a[1] == a[3]) && (a[3] == a[4]) && (a[4] == a[6])
这是我一开始的写法,可以发现是错的,因为忽略了A不等于B的条件,11111111也是符合上述的判断,但是并不符合题意
所以我们还得限制A不等于B
正确的写法应该是:(a[0] != a[1]) && (a[0] == a[2]) && (a[2] == a[5]) && (a[5] == a[7]) && (a[1] == a[3]) && (a[3] == a[4]) && (a[4] == a[6])
修改后,再次提交,仍然WA,检查之后发现没有判断是否是合法日期
再次修改,依然WA,又一次检查,发现i的范围给小了,我一开始只把n限制在了89991213,当时看到最大的数据范围就是这个,所以想当然的把89991213当成最大的,但是如果输入的n是89991213,那么它之后的回文日期必然大于89991213,终于AC了,但是代码写的还是挺烂的。。
总结来说,是个简单题,但是要注意细节
又用到了常考的判断日期的合法性

#include<bits/stdc++.h>
using namespace std;
int a[9];
int b[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int check1(int n) {
	int k = 0;
	int m = n;
	while (n > 0) {
		a[k++] = n % 10;
		n /= 10;
	}
	if (a[0] == a[7] && a[1] == a[6] && a[2] == a[5] && a[3] == a[4]) {
		return 1;
	} else
		return 0;
}
int check2(int n) {
	int k = 0;
	int m = n;
	while (n > 0) {
		a[k++] = n % 10;
		n /= 10;
	}

	if ((a[0] != a[1]) && (a[0] == a[2]) && (a[2] == a[5]) && (a[5] == a[7]) && (a[1] == a[3]) && (a[3] == a[4]) && (a[4] == a[6])) {
		return 1;
	} else
		return 0;
}
int judge(int year, int month, int day) {
	if (month == 0 || month > 12) {
		return 0;
	}
	if (month != 2) { //不是二月份的时候
		if (day > b[month] || day == 0)
			return 0;
	}
	if (month == 2) { //是二月
		//判断是否是闰年
		if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
			b[month] = 29;
			if (day > b[month] || day == 0)
				return 0;

		} else {
			b[month] = 28;
			if (day > b[month] || day == 0)
				return 0;
		}
	}
	return 1;
}
int main() {
	int n;
	cin >> n;
	int flag = 0;
	int flag1 = 0;
	for (int i = n + 1; i <= 99999999; i++) {
		int year = i / 10000;
		int month = i / 100 % 100;
		int day = i % 100;
		int ans = judge(year, month, day);
		if (ans == 1) {
			int flag1 = check1(i);
			if (flag1 == 1) {
				cout << i << endl;
				break;
			}
		}
	}
	for (int i = n + 1; i <= 99999999; i++) {
		//判断日期是否合法
		int year = i / 10000;
		int month = i / 100 % 100;
		int day = i % 100;
		int ans = judge(year, month, day);
		if (ans == 1) {
			int flag = check2(i);
			if (flag == 1) {
				cout << i << endl;
				break;
			}
		}
	}
}

蓝桥杯2020第十一届省赛第一场 第二题 纪念日
在这里插入图片描述
思路:算出这两个日期之间有多少天即可,注意闰年有29天

#include<bits/stdc++.h>
using namespace std;
int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int year)
{
	if(year%400==0||(year%4==0&&year%100!=0))
	{
		return true;
	}
	else
	{
		return false;
	} 
}
int main()
{
	int sum=0;
	for(int i=1921;i<=2020;i++)
	{
		bool flag=check(i);
		if(flag)
		{
			a[2]=29;
		}
		else
		{
			a[2]=28;
		}
		if(i==1921)
		{
			for(int j=8;j<=12;j++)
			{
				sum+=a[j];
			}
			sum+=8;
		}
		else if(i==2020)
		{
			for(int j=1;j<=6;j++)
			{
				sum+=a[j];
			}
			sum+=1;
		} 
		else
		{
			for(int j=1;j<=12;j++)
		    {
				sum+=a[j];
			}
		}
	}
	cout<<sum*24*60<<endl;
}
//52038720

蓝桥杯2020第十一届省赛第二场 第四题 跑步锻炼
在这里插入图片描述
思路一:暴力枚举从20000101到20201001的所有合法日期,如果日期合法,判断是不是月初或者周一,有个小问题,怎么去计算它是星期几,由2000年1月1日是周六,我们可以得出2000年1月2日是星期天,算出给定日期是从该天起过了x天,然后输出x%7,当天即为星期几,也就是找当前最近的是周日的那天开始枚举,最后别忘了加上1月1日的2千米和1月2日的1千米

#include<bits/stdc++.h>
using namespace std;
int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
//2000.1.1(周六)----->2020.10.1
int check(int year, int month, int day) {
	if (month == 0 || month > 12) {
		return false;
	}
	if (month != 2) { //不是二月份的时候
		if (day > a[month] || day == 0)
			return false;
	}
	if (month == 2) { //是二月
		//判断是否是闰年
		if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
			a[month] = 29;
			if (day > a[month] || day == 0)
				return false;

		} else {
			a[month] = 28;
			if (day > a[month] || day == 0)
				return false;
		}
	}
	return true;
}
int main() {
	int ans=3;
	int pass=0;
	for (int i = 20000103; i <= 20201001; i++) {
		int day = i % 100;
		int month = i / 100 % 100;
		int year = i / 10000;
		bool flag = check(year, month, day);
		if (flag) {
			pass++;
			int weekday=pass%7;
			if(weekday==1||day==1)
			{
				ans+=2;
			}
			else
			ans+=1;			
		}
	}
	cout<<ans<<endl; 
}

思路二:后面看了看别人的做法,处理时间是比较巧妙的,感觉像是模拟,其中对星期几的处理也十分的巧妙

#include<bits/stdc++.h>
using namespace std;
int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main() {
	int year = 2000;
	int month = 1;
	int day = 1;
	int ans = 0;
	int weekday = 6;
	while (year != 2020 || month != 10 || day != 1) { //||符号相当于数学中的并集,必须是三个都为false,条件才为false
		//判断是否是闰年
		//闰年2月29天,平年2月28天
		if ((year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0)) {
			a[2] = 29;
		} else {
			a[2] = 28;
		}
		day++;
		weekday = (weekday + 1) % 7;
		if (day > a[month]) {
			month++;
			day = 1;
		}
	  if (month > 12) {
			month = 1;
			year++;
		}
		if(day==1||weekday==1)
		{
			ans+=2;
		}
		else
		{
			ans+=1;
		}
	}
	cout<<ans+2<<endl;
}*

总结
总结一下近几年有关日期类的问题,需要掌握以下几个点

  • 判断闰年
  • 检测日期的合法性
  • 判断回文
  • 给一个日期,告诉你是星期几,然后根据这个去计算另一个日期是星期几,一般找星期天的日期,以那天为基准点,该天起过了x天,然后输出x%7
int pass=0;
	for (int i = 20000103; i <= 20201001; i++) {
		int day = i % 100;
		int month = i / 100 % 100;
		int year = i / 10000;
		bool flag = check(year, month, day);
		if (flag) {
			pass++;
			int weekday=pass%7;//weekday就是计算出来的星期几
			if(weekday==1||day==1)
			{
				ans+=2;
			}
			else
			ans+=1;			
		}
	}
  • 给定年月日,计算经过n天后对应的日期
void pass(int y, int m, int d, int n) {
	while (n--) {
		d++;
		if (d > get(y, m)) m++, d = 1;
		if (m > 12) y++, m = 1;//跟上面提到的巧妙的做法如出一辙
	}
	printf("%d-%02d-%02d\n", y, m, d);
}

  • 用年份构造回文日期
int year = 2021;
int d = year, x = year;
for(int i = 0; i < 4; i++) {
	d = d * 10 + x % 10;
	x /= 10;
}
// d就是构造的回文日期了

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 23:08:08  更:2022-04-01 23:10:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:53:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码