一、题目
二、题目解读
本题是日期模拟题,把日期按照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日这段时间,练习篮球的天数是多少?
三、题目分析
现在我们来分析解决题目的几个关键点:
-
- 从 2000 到 2024 哪些是闰年,闰年的 2 月有 29 天
-
- 从八位数字中取得年、月、日
-
- 从 20000101 到 20240413 中筛选有效日期数字
-
- 进行笔画判断
那么我们现在一步一步解决
第一点:判断闰年
闰年的条件是我们必须要掌握的,要么能被 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))
{
//输入相关逻辑代码;
}