日期模板
日期模板我建议大家尽量的利用函数来使总体的代码简洁化,并且这样可以让自己的思路更加清晰、明亮,关于日期的题目大部分都需要这个模板
判断是否是闰年
判断一个年份是否是闰年有两个独立条件,只要满足其一就可以判定是否为闰年。
如果这个年份能够被400整除或者能被4整除而不能被100整除,那样我们就可以判断该年是闰年,否则不是
代码如下:
bool leap_y(int y){
if(y % 400 == 0 || y % 4 == 0 && y % 100 ! = 0)
return true;
return false;
}
判断年月日是否合法
年份的取值范围要根据题中具体条件来写,而月、日的范围都是固定的,月份要在[1,12]区间内,日份要在[1,具体的月份日期内]区间内
另外,要把整年的月份用数组表述出来
int month_m [13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
为了不特殊判断下标0,需要开13个元素
回文日期
题目描述
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。
给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
输入描述
输入包含一个八位整数 N,表示日期。
对于所有评测用例,
10000101 ≤ N ≤ 89991231
保证 N 是一个合法日期的 8 位数表示。
输入输出样例
示例
输入
20200202
输出
20211202
21211212
在这里我用字符串定义8位数,然后使用函数stoi和to_string来截取和还原字符串
代码如下
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
//判断闰年
bool checkleapyear(int x) {
if(x%400==0||(x%4==0&&x%100!=0))
return true;
else
return false;
}
//判断是否为ABABBABA型的回文日期
bool checkstyle(string x) {
if(x[0]==x[2]&&x[1]==x[3]&&x[0]!=x[1])
return true;
else
return false;
}
//枚举月份
int arr[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int main () {
string S,ans1="",ans2="";//ans1="",ans2=""代表字符串为空
string s,t,year;
int y,m,d,i;
cin>>S;
year=S.substr(0,4);//截取年份
for(i=stoi(year); ans1==""||ans2==""; i++) {
s=to_string(i);t=to_string(i);
reverse(t.begin(),t.end());//将年份逆序
s+=t;//正序年份+逆序年份
if(s<=S) continue;//判断下一个回文日期,如果是当前日期则跳过
y=stoi(s.substr(0,4)),m=stoi(s.substr(4,2)),d=stoi(s.substr(6,2));//截取年月日
if(checkleapyear(y))
arr[2]=29;
else
arr[2]=28;
if(m<1||m>12) continue;
if(d<1||d>arr[m]) continue;
if(ans1=="") ans1=s;
if(checkstyle(s)&&ans2=="") ans2=s;
}
cout<<ans1<<endl<<ans2<<endl;
return 0;
}
总结
如果有更好的优化代码或者有疑问可以评论一起讨论