日期问题
本文主要总结一下蓝桥杯中经常出现的日期问题的一些处理策略。
1.格式化读入输出
2.nsprintf
3.reverse判断回文
4.模板
格式化读入输出
在很多日期问题中,输入格式为一个8位字符串代表的年月日或者题目要求输出格式为一个8位的年月日。
这种情况下,我们使用格式化scanf和printf可以很好的简化问题
cpp
scanf("%4d%2d%2d",&a,&b,&c);
//不需要在格式符前面加0,只需要写出位数有多少即可
printf("%04d%02d%02d",a,b,c);
//4d表示4位小数,0表示不足的位数前面补0
snprintf
有时我们在解题过程中需要将某个8位日期(原本由年月日3个int表示)赋值给某个字符串(通常是便于一些字符串操作),比较方便的方法是使用snprintf()
cpp
int year;
int month;
int day;
char buf[10];
snprintf(buf,sizeof buf,"%04d%02d%02d",year,month,day);
string s1;
s1=buf;//字符数组可以直接为string赋值
reverse判断回文
cpp
string s1;
string s2=s1;
reverse(s2.begin(),s2.end());
return s1==s2;
模板
本模板以11届蓝桥杯P6为例
(11届C++A组省赛P6回文日期)[https://www.lanqiao.cn/problems/348/learning/\]
cpp
//17:27
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
using namespace std;
string a,b;
struct node{
int year,month,day;
};
node s,t;
node str_to_node(string x){
node res;
res.year=(x[0]-'0')*1000+(x[1]-'0')*100+(x[2]-'0')*10+(x[3]-'0');
res.month=(x[4]-'0')*10+(x[5]-'0');
res.day=(x[6]-'0')*10+(x[7]-'0');
return res;
}
bool is_hui(node x){
char buf[10];
snprintf(buf,sizeof buf,"%04d%02d%02d",x.year,x.month,x.day);
string s1=buf;
string s2=s1;
reverse(s2.begin(),s2.end());
return s1==s2;
}
bool is_lunar(int year){
if (year%4==0&&year%100!=0)
return true;
if (year%400==0)
return true;
return false;
}
int ans;
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int main(){
cin>>a>>b;
s=str_to_node(a);
t=str_to_node(b);
if (is_hui(s))
ans++;
while(true){
if (is_lunar(s.year)){
month[2]=29;
}
s.day++;
if (s.day>month[s.month]){
s.day=1;
s.month++;
}
if (s.month>12){
s.year++;
s.month=1;
month[2]=28;
}
if (is_hui(s)){
ans++;
}
if (s.year>t.year||(s.year==t.year&&s.month>t.month)||(s.year==t.year&&s.month==t.month&&s.day>t.day)){
break;
}
}
cout<<ans<<endl;
return 0;
}