蓝桥2017G题

日期问题

问题描述:

小明正在整理一批文献,这些文献中出现很多日期,小明知道这些日期都在1960年1月1日至2059年12月31日之间。令小明头疼的是,这些日期的格式非常不统一,有采用“年/月/日”的,有采用“月/日/年”的,还有采用“日/月/年”的。更加麻烦的是,年份都省略的前两位,使得文献上的一个日期存在很多可能的日期与其对应。例如02/03/04,可能是2002年03月04日,20004年02月03日或2004年03月02日。给出一个文献的日期,你能帮助小明判断有哪些可能的日期与其对应吗?

输入格式

输出若干不同的日期,每个日期一行,格式是“yyyy-mm-d”。多个日期按从早到晚的顺序排列。

样例输入

02/03/04

样例输出

2002-03-04

2004-02-03

20004-03-02

解析

本题的思路很简单,将输入的3个数据分别进行年月日的合法判断,如果合法就输出。但是求解本题要注意以下两点:

(1)月份数据的表示

由于每月的天数没有规律性,所以最好的方法就是利用数组将每月的天数表示出来,如:

int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

这里还要注意闰年的问题,如果是闰年,则2月的数据就会有所不同,可以采用另一个数组储存,如:

int leapdays[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};

(2)合法年月日的储存
对于一组数据,可能会出现重复的合法年月日。例如:输入01/01/01,则3组合法数据都是2001-01-01,所以这里需要进行去重。
去重时可以判断这三个数是否相等,也可用c++中的STL set容器自动去重。

参考程序

c语言

#include<stdio.h>
int days[14]={0,31,28,31,30,31,30,31,31,30,31,30,31};//正常年月份天数
int leapdays[14]={0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年时月份天数
int data[4][4],i;
int leapyear(int y)
{
if((y%4==0&&y%100!=0)||y%400==0)
return 1;
else return 0;
}//判断平闰年
void check(int y,int m,int d)
{
if(y<=60) y=19*100+y
else y=20*100+y;//年份还原是20还是21世纪
if (m>12) return;//大于12月份明显不符
if(leapyear(y))
  if(leapdays[m]<d) return;
else if(days[m]<d) return;//当月天数小于d则不符
if(i>0)
for(int j=0;j<i;j++)
{
if(data[j][0]==y&&data[j][1]==m&&data[j][2]==d)
return;
}
data[i][0]=y;
data[i][1]=m;
data[i][2]=d;
i++
}//检查函数
int main()
{
int a,b,c,e,f,g;
int d[3];
i=0;
scanf("%d %d %d",&a,&b,&c);
check(a,b,c);
check(c,a,b);
check(a,b,a);
for(int j=0;j<i;j++)
{
d[j]=data[j][0]*10000+data[j][1]*100+data[j][2];
}
sort(d,d+i);
for(int j=0;j<i;j++)
{
e=d[j]/10000;
f=(d[j]/100)%100;
g=d[j]%100;
printf("%d-%02d-%02d\n",e,f,g);
}
return 0;
}

c++

#include<iostream>
#include<sstream>
#include<set>
using namespace std;
bool isleap(int a)
{
	return (a % 400 == 0 && (a % 100 != 0 || a % 4 == 0));
}
void is(int n, string& s)
{
	stringstream ss;
	ss << n;
	ss >> s;
}
string f(int year, int month, int day)
{
	if (year >= 0 && year <= 59) year += 2000;
	if (year >= 60 && year <= 99)        year += 1900;
	if (month < 1 || month>13)return " ";
	if (day < 1 || day>31)return " ";
	bool _isleap = isleap(year);
	switch (month)
	{
	case 2:
		if (_isleap && day > 29) return " ";
		if (!_isleap && day > 28)return " ";
		break;
	case 4:
		if (day > 30) return "";
		break;
	case 6:
		if (day > 30)return " ";
		break;
	case 9:
		if (day > 30)return " ";
		break;
	case 11:
		if (day > 30) return " ";
		break;
	default:
		break;
	}
	string _a, _b, _c;
	is(year, _a);
	is(month, _b);
	is(day, _c);
	if (_b.length() == 1) _b = '0' + _b;
	if (_c.length() == 1) _c = '0' + _c;
	return _a + "-" + _b + "-" + _c;
}
int main()
{
	string in;
	cin >> in;
	int a, b, c;
	a = (in[0] - '0') * 10 + (in[1] - '0');
	b = (in[3] - '0') * 10 + (in[4] - '0');
	c = (in[6] - '0') * 10 + (in[7] - '0');
	string case1 = f(a, b, c);
	string case2 = f(c, a, b);
	string case3 = f(c, b, a);
	set<string> ans;
	if (case1 != " ") ans.insert(case1);
	if (case2 != " ") ans.insert(case2);
	if (case3 != " ") ans.insert(case3);
	for (set<string>::iterator it = ans.begin(); it != ans.end(); it++)
	{
		cout << *it << endl;
	}
	return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

typedef struct{
    int year, month, day;
}date;

bool isyn(int y){
    return (y % 4 == 0) || (y % 100 && y % 400 == 0);
}

void print(const date &d){
    printf("%02d-%02d-%02d\n", d.year, d.month, d.day);
}

bool compare(const date &d1, const date &d2){
    if(d1.year != d2.year){
        return d1.year < d2.year;
    }
    if(d1.month != d2.month){
        return d1.month < d2.month;
    }
    return d1.day < d2.day;
}

bool check(const date &d){
    static int month_days[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if(isyn(d.year)){
        month_days[2] = 29;
    }else{
        month_days[2] = 28;
    }

    if(d.year < 1960 || d.year > 2059){
        return false;
    }
    if(d.month < 1 || d.month > 12){
        return false;
    }
    if(d.day < 1 || d.day > month_days[d.month]){
        return false;
    }
}

int main()
{
    int aa, bb, cc;
    scanf("%d/%d/%d", &aa, &bb, &cc);
    date d[6] = {
        {2000 + aa, bb, cc},
        {1900 + aa, bb, cc},
        {2000 + cc, aa, bb},
        {1900 + cc, aa, bb},
        {2000 + cc, bb, aa},
        {1900 + cc, bb, aa}
    };
    sort(d, d + 6, compare);
    for(int i = 0; i < 6; ++ i){
        if(check(d[i])){
            print(d[i]);
        }
    }
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值