日期问题

日期问题

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

输入格式
一个日期,格式是”AA/BB/CC”。
即每个’/’隔开的部分由两个 0-9 之间的数字(不一定相同)组成。

输出格式
输出若干个不相同的日期,每个日期一行,格式是”yyyy-MM-dd”。
多个日期按从早到晚排列。

数据范围
0≤A,B,C≤9

输入样例:
02/03/04

输出样例:
2002-03-04
2004-02-03
2004-03-02

思路:原先我的思路就是模拟整个过程,写入,合法判断,从小到大排序,去重,输出,写了150多行代码后AC75%。
代码如下:

using namespace std;

bool leagal(int year, int month, int day)
{
	if (month <= 0 || day <= 0)
	{
		return false;
	}
	int date[2][12] = { {31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31} };
	if ((year % 4 && year % 100 != 0) && month <= 12 && day <= 31|| year % 400 == 0 )
	{
		if (date[1][month - 1] >= day)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else if(month <= 12 && day <= 31)
	{
		if (date[0][month - 1] >= day)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	return false;
}

int main()
{
	int x1, x2, x3, N = 0;
	int arr[3][3] = { 0 };
	scanf_s("%d/%d/%d", &x1, &x2, &x3);
	int t1 = x1, t2 = x2, t3 = x3;
	if (t1 < 100)
	{
		if (t1 < 60)t1 += 2000;
		else t1 += 1900;
		if (leagal(t1, t2, t3))
		{
			arr[N][0] = t1;
			arr[N][1] = t2;
			arr[N][2] = t3;
			N++;
		}
	}
	t1 = x1, t2 = x2, t3 = x3;
	if (t3 < 100)
	{
		if (t3 < 60)t3 += 2000;
		else t3 += 1900;
		if (leagal(t3, t1, t2))
		{
			arr[N][0] = t3;
			arr[N][1] = t1;
			arr[N][2] = t2;
			N++;
		}
		if (leagal(t3, t2, t1))
		{
			arr[N][0] = t3;
			arr[N][1] = t2;
			arr[N][2] = t1;
			N++;
		}
	}
	int min_year = arr[0][0], min_month = arr[0][1], min_day = arr[0][2];
	for (int i = 0; i < N - 1; i++)
	{
		for (int j = 0; j < N - i - 1; j++)
		{
			if (arr[j][0] > arr[j + 1][0])
			{
				int t = arr[j][0];
				arr[j][0] = arr[j + 1][0];
				arr[j + 1][0] = t;
				t = arr[j][1];
				arr[j][1] = arr[j + 1][1];
				arr[j + 1][1] = t;
				t = arr[j][2];
				arr[j][2] = arr[j + 1][2];
				arr[j + 1][2] = t;
			}
			else if (arr[j][0] == arr[j + 1][0] && arr[j][1] > arr[j + 1][1])
			{
				int t = arr[j][0];
				arr[j][0] = arr[j + 1][0];
				arr[j + 1][0] = t;
				t = arr[j][1];
				arr[j][1] = arr[j + 1][1];
				arr[j + 1][1] = t;
				t = arr[j][2];
				arr[j][2] = arr[j + 1][2];
				arr[j + 1][2] = t;
			}
			else if (arr[j][0] == arr[j + 1][0] && arr[j][1] == arr[j + 1][1] && arr[j][1] > arr[j + 1][1])
			{
				int t = arr[j][0];
				arr[j][0] = arr[j + 1][0];
				arr[j + 1][0] = t;
				t = arr[j][1];
				arr[j][1] = arr[j + 1][1];
				arr[j + 1][1] = t;
				t = arr[j][2];
				arr[j][2] = arr[j + 1][2];
				arr[j + 1][2] = t;
			}
		}
	}

	for (int i = 0; i < N; i++)
	{
		if (arr[i][0] == arr[i + 1][0] && arr[i][1] == arr[i + 1][1] && arr[i][2] == arr[i + 1][2])
		{
			for (int j = i + 1; j < N - 1; j++)
			{
				arr[j][0] = arr[j + 1][0];
				arr[j][1] = arr[j + 1][1];
				arr[j][2] = arr[j + 1][2];
			}
			N--;
		}
	}

	for (int i = 0; i < N; i++)
	{
		cout << arr[i][0] << "-";
		if (arr[i][1] < 10)
		{
			cout << 0 << arr[i][1] << "-";
		}
		else
		{
			cout << arr[i][1] << "-";
		}
		if (arr[i][2] < 10)
		{
			cout << 0 << arr[i][2] << endl;
		}
		else
		{
			cout << arr[i][2] << endl;
		}
	}
	return 0;
}

后来参考了网上的一种写法,发现十分之妙。
思路:从1960年1月1日至2059年12月31日看做数字,逐个遍历,即遍历(19600101~20591231)这么多数,遍历时判断合法与是否是输入。

注意输出:例如输出1960-01-01,应使用
printf("%02d-%02d-%02d",year,month,day);//其中%02d意思是不足2位高位补0

代码如下:

using namespace std;
int mon[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
bool check(int year,int month,int day)
{
	if (month == 0 || day == 0)return false;
	if (month > 12 || day > 31)return false;
	if (month == 2)
	{
		if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
		{
			if (day > 29)return false;
		}
		else
		{
			if (day > 28)return false;
		}
	}
	else
	{
		if (day > mon[month])return false;
	}
	return true;
}
int main()
{
	int a, b, c;
	scanf_s("%d/%d/%d", &a, &b, &c);
	for (int i = 19600101; i <= 20591231; i++)
	{
		int year = i / 10000;
		int month = i % 10000 / 100;
		int day = i % 100;
		if (check(year,month,day))
		{
			if ((year % 100 == a && month == b && day == c) || (year % 100 == c && month == b && day == a) || (year % 100 == c && month == a && day == b))
			{
				printf("%02d-%02d-%02d\n", year, month, day);
			}
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值