[蓝桥杯2017初赛]日期问题
- Description
小明正在整理一批历史文献。这些历史文献中出现了很多日期。
小明知道这些日期都在1960年1月1日至2059年12月31日。
令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
-
Input
一个日期,格式是"AA/BB/CC"。 (0 <= A, B, C <= 9)
-
Output
输出若干个不相同的日期,每个日期一行,格式是"yyyy-MM-dd"。
多个日期按从早到晚排列。
分析
这个题不难,但是非常的麻烦,呜呜呜本菜鸟写了3个小时才改好。
题目只有三种格式,y/m/d,m/d/y,d/m/y。而年份有2种情况,19XX和20XX,由于输入格式为AA/BB/CC,所以对于每一种格式,分别判断1900+AA和2000+AA即可,当AA,BB,CC都相同时,则涉及到去重问题
STL自定义排序
2种方式:
第一种,直接在定义结构体时重载小于号运算符,这种方式排序时还是正常写法:
bool operator<(const node &a) //重载小于号,方便排序
{
if((*this).y!=a.y) //年份不同,直接比较年份
return (*this).y<a.y;
else if((*this).m!=a.m) //年份不同,比较月份
return (*this).m<a.m;
else //y和m都相等
return (*this).d<a.d;
}
sort(v,begin(),v.end())
第二种,在结构体外写一个比较函数,这种方式排序时要加上函数名
bool cmp(node a,node b) //自定义排序
{
if(a.y!=b.y)
return a.y<b.y;
else if(a.m!=b.m) //a.y=b.y
return a.m<b.m;
else //y和m都相等
return a.d<b.d;
}
sort(v,begin(),v.end(),cmp)
STL结构体去除重复项
对于vector容器,排序后使用v.erase(unique(begin(v), end(v)), end(v))语句
即可去重重复项,但对于结构体而言,首先要重载“==”运算符
貌似set容器在结构体里重载运算符更简单?
bool operator==(const node&a) //重载等于号,方便结合unique去重
{
return (*this).y==a.y&&(*this).m==a.m&&(*this).d==a.d;
}
v.erase(unique(begin(v), end(v)), end(v))
- AC代码
#include <bits/stdc++.h>
using namespace std;
struct node //定义结构体
{
int y,m,d;
node(int yy,int mm,int dd):y(yy),m(mm),d(dd){}
bool operator<(const node &a) //重载小于号,方便排序
{
if((*this).y!=a.y) //年份不同,直接比较年份
return (*this).y<a.y;
else if((*this).m!=a.m) //年份不同,比较月份
return (*this).m<a.m;
else //y和m都相等
return (*this).d<a.d;
}
bool operator==(const node&a) //重载等于号,方便结合unique去重
{
return (*this).y==a.y&&(*this).m==a.m&&(*this).d==a.d;
}
};
//结合判断闰年,直接返回y年m月的日期
int a[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
bool leap(int y) //判断闰年
{
return y%4==0&&y%100!=0||y%400==0;
}
bool ok(int y,int m,int d) //判断年月日是否在给定范围内
{
if(y>=1960&&y<=2059&&m>=1&&m<=12&&d>=1&&d<=a[leap(y)][m])
return 1;
return 0;
}
bool cmp(node a,node b) //自定义排序 --没用到
{
if(a.y!=b.y)
return a.y<b.y;
else if(a.m!=b.m) //a.y=b.y
return a.m<b.m;
else //y和m都相等
return a.d<b.d;
}
int main()
{
vector<node>v;
int y,m,d;
char ch;
cin>>y>>ch>>m>>ch>>d;
//讨论 y/m/d 的情况
int y1=1900+y,m1=m,d1=d;
if(ok(y1,m1,d1))//结合判断闰年,直接返回y年m月的日期
v.push_back(node(y1,m1,d1));
y1=2000+y;
if(ok(y1,m1,d1))
v.push_back(node(y1,m1,d1));
//讨论 m/d/y 的情况
int y2=1900+d,m2=y,d2=m;
if(ok(y2,m2,d2))
v.push_back(node(y2,m2,d2));
y2=2000+d;
if(ok(y2,m2,d2))
v.push_back(node(y2,m2,d2));
//讨论 d/m/y 的情况
int y3=1900+d,m3=m,d3=y;
if(ok(y3,m3,d3))
v.push_back(node(y3,m3,d3));
y3=2000+d;
if(ok(y3,m3,d3))
v.push_back(node(y3,m3,d3));
sort(v.begin(),v.end());//排序,从早到晚输出
v.erase(unique(begin(v), end(v)), end(v));//去除重复项
for(vector<node>::iterator it=v.begin();it!=v.end();it++)
printf("%04d-%02d-%02d\n",(*it).y,(*it).m,(*it).d);
//cout<<y<<" "<<m<<" "<<d;
//cout<<ok(2013,2,28);
return 0;
}
太难了!呜呜呜
看完觉得有用点个赞吧