蓝桥杯【艺术与蓝桥】【日期问题】【2024省赛】——C++

一、题目

题目

二、题目解读

本题是日期模拟题,把日期按照YYYYMMDD八位数来表示,如2024年4月13日表示为 20240413,每一个数字对应汉字的笔画数题目已经给出,现在要看某一天的日期对应汉字的笔画数和 50 比较,如果大于 50 就练习篮球,如果小于等于 50,就去练习书法。

示例数据2024年1月1日这天,数字表示是 20240101,对应汉字是“二零二四零一零一”,笔画数为 “2+13+2+5+13+1+13+1=50”,小于等于 50,那么练习书法。

现在要统计从2000年1月1日到2024年4月13日这段时间,练习篮球的天数是多少?

三、题目分析

现在我们来分析解决题目的几个关键点:

    1. 从 2000 到 2024 哪些是闰年,闰年的 2 月有 29 天
    1. 从八位数字中取得年、月、日
    1. 从 20000101 到 20240413 中筛选有效日期数字
    1. 进行笔画判断

那么我们现在一步一步解决
第一点:判断闰年
闰年的条件是我们必须要掌握的,要么能被 4 整除的时候不能被 100 整除,要么能被 400 整除

if((year%4==0 && year%100!=0) || year%400==0) return true;

第二点:从八位数字中取得年、月、日
这里就需要我们对除运算和模运算比较熟悉了

int year=i/10000;
int month=i%10000/100;
int day=i%100;

第三点:筛选有效日期数字
有效日期数字需要后四位代表月的month要在1到12之间,代表日的day根据月份,找到对应的天数,比如 1,3,5,7,8,10,12 月份有31天,4,6,9,11 月份有 30 天,2 月闰年有 29 天,平年有 28 天。

if(month>=1 && month<=12 && day>=1 && day<=getday(year,month))
{
	int day=i%100;
}

getday()函数用来获得每个月对应的天数,用 m【13】数组来用m【i】对应 1 到 12 月的天数,这里细节是 m【0】位置设为 0,那么 i 对应的m【i】就是第 i 月的天数

int getday(int year,int month)
{
	int m[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
	if(run(year)&&month==2) return m[month]+1;
	else return m[month];
}

run()函数是用来判断是否是闰年的,是闰年则返回true,否则返回false

bool run(int year)
{
	if((year%4==0 && year%100!=0) || year%400==0) return true;
	else return false;
}

第四步:笔画判断
用 ret 来接收笔画的值,我们可以定义数组int a[10]={13,1,2,3,5,4,4,2,2,2};,这样就对应了零到九每个汉字的笔画数了。我们的ret要统计每一位的笔画数,在筛选合法日期中,我们九可以直接加上月日的笔画了,这里的月和日都是两位数,进行整除10的处理得到的是十位,取模 10 的处理得到的是个位

if(month>=1&&month<=12&&day>=1&&day<=getday(year,month))
{
    int day=i%100;
    ret=a[day%10]+a[day/10]+a[month%10]+a[month/10];
}	

之后再加上年的笔画,由于这里的年是 2000 到 2024 范围,千位和百位是固定的 2 和 0,所以我们后面直接加上 a【0】和 a【2】

ret+=a[year%10]+a[year/10%10]+a[0]+a[2];

如果ret大于50,那我们的答案ans就自增1

if(ret>50) ans++;

注意细节:
由于我们每次对八位数字循环判断,ret 需要记得在最开始重置为 0,否则就不能用 ret 准确记录笔画数了

四、代码

#include <iostream>
using namespace std;
int a[10]={13,1,2,3,5,4,4,2,2,2};
int ret,ans;
bool run(int year)
{
	if((year%4==0 && year%100!=0) || year%400==0) return true;
	else return false;
}

int getday(int year,int month)
{
	int m[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
	if(run(year)&&month==2) return m[month]+1;
	else return m[month];
}
int main()
{
  
    for(int i=20000101;i<=20240413;i++)
    {
    	ret=0;
    	int year=i/10000;
    	int month=i%10000/100;
    	int day=i%100;
    	if(month>=1&&month<=12&&day>=1&&day<=getday(year,month))
    	{
    		int day=i%100;
    		ret=a[day%10]+a[day/10]+a[month%10]+a[month/10];
		}		
		ret+=a[year%10]+a[year/10%10]+a[0]+a[2];
		if(ret>50) ans++;
	}
	cout<<ans;
    return 0;
}   

运行结果
ps:如果是其他语言如python或者Java的,可以借用ai工具,把cpp的代码转换一下。如果有其他思路的也欢迎大家在评论区留言交流

五、日期问题相关模板

5.1判断闰年模板

bool run(int year)
{
	if((year%4==0 && year%100!=0) || year%400==0) return true;
	else return false;

5.2获得月份对应的天数

int getday(int year,int month)
{
	int m[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
	if(run(year)&&month==2) return m[month]+1;
	else return m[month];
}

5.3筛选有效日期

if(month>=1 && month<=12 && day>=1 && day<=getday(year,month))
{
	//输入相关逻辑代码;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值