蓝桥杯省赛真题——回文日期

题目描述

2020年春节期间,有一个特殊的日期引起了大家的注意:2020年2月2日。因为如果将这个日期按“yyyymmmdd”的格式写成一个8位数是20200202, 恰好是一个回文数。我们称这样的日期是回文日期。

有人表示 20200202是“千年一遇”的特殊日子。对此小明很不认同,因为不到2年之后就是下一个回文日期:20211202即2021年12月2日。

也有人表示20200202 并不仅仅是一个回文日期,还是一个ABABBABA型的回文日期。对此小明也不认同, 因为大约 100年后就能遇到下一个ABABBABA型的回文日期:21211212即2121年12月12日。算不上“千年一遇”,顶多算“千年两遇”。

给定一个8位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。

输入描述

输入包含一个八位整数N, 表示日期。对于所有评测用例, 10000101≤N≤89991231, 保证 N是一个合法日期的8位数表示。

输出描述

输出两行,每行1个八位数。第一行表示下一个回文日期, 第二行表示下一个ABABBABA型的回文日期。

示例

输入

20200202

输出

20211202

21211212

思路

思路一

1.创建一个数组a,里面包含从1000 0000~9999 9999所有的整数;

2.然后对输入的数n先+1再进行取模和取商的运算,将得到的八个整数存放到一个数组b内;

3.接着进行反转,即原来个位上的数变成千万位上的数,得到数c;

4.然后遍历数组a,将a与c进行对比,

如果c=a[i],则输出a[i],

反之则n+1,重复2~4操作。

(上手操作了一下,难度很大很大,而且代码会变得很复杂,所以这个被舍弃了)

思路二

1.首先观察输入的是一个日期,那么后四位数必须符合日期的规则。

2.那么只需要对后四位进行一个设定,就可以控制这个八位数(镜像对称)。

3.把月和日规划好后,反转输入年份。(数组内每一个都是回文日期)

4.遍历数组进行比较即可。

解题

1.首先解决月和日

一年365天,需要创建一个存放365组数据的数组,其次将每个数字单独存放,方便后续计算。这样看来一个二维数组存取都非常方便a[365][4]。

一年十二个月,每个月的天数都是不一样的,可以设置一个循环变量i,判断月份。

for (i = 1; i <= 12; i++)
	{
		if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
		{
			day = 31;
			k=init(a, k, i, day);	
		}
		else if (i == 4 || i == 6 || i == 9 || i == 11)
		{
			day = 30;
			k = init(a, k, i, day);
		}
		else
		{
			day = 28;
			k = init(a, k, i, day);
		}
	}

int init(int a[365][4], int k, int i, int day)
{
	int j;
	for (j = 1; j <= day; j++)
	{
		a[k][0] = i / 10;
		a[k][1] = i % 10;
		a[k][2] = j / 10;
		a[k][3] = j % 10;
		k++;
	}
	return k;
}

int init(int a[365][4], int k, int i, int day)是我封装的一个初始化函数,里面的逻辑很简单,i是一个从1-12的数字,数组的0和1列都是用来存放月份的,i%10得到个位,i/10得到十位,十位为0则存0.

循环结束以后,数组内存放的就是一年里面全部的日期。(不包含闰年2.29)。

这里单独说一下0229是闰年的二月,那么9220明显不是闰年,所以直接不用去考虑闰年这个问题。

2.其次解决年份

因为这个年份和日期是镜像对称的,那么0316所对应的年份就是6*1000+1*100+3*10+0*1;

那么我们可以一步到位一下,直接解决年月日。创建一个数组b[365]存放365个数据。

for (i = 0; i < 365; i++)
	{
		b[i] = 1000 * a[i][0] + 100 * a[i][1] + 10 * a[i][2] + a[i][3] +
			10000 * a[i][0] + 100000 * a[i][1] + 1000000 * a[i][2] + 10000000 * a[i][3];		
	}

现在b[365]内存放的就是所有有效的八位数的回文数字。

蓝桥杯省赛真题——回文日期_第1张图片

3.然后解决问题

题目要求:第一行表示下一个回文日期

那么我们可以把数组b进行一个排序,从小到大排序,然后与输入的八位数字n比较,输出比n大的的一个b[i]。这里我采用的是冒泡排序。

for (i = 0; i < 364; i++)
	{
		for (j = 0; j < 364 - i; j++)
		{
			if (b[j] > b[j + 1])
			{
				temp = b[j];
				b[j] = b[j + 1];
				b[j + 1] = temp;

			}
		}
	}

接着遍历然后输出,解决第一个问题。

for (i = 0; n >= b[i]; i++)
		;
	printf("%d\n", b[i]);

题目要求:第二行表示下一个ABABBABA型的回文日期

可以创建一个特殊的回文日期数组s[i],里面存放的全部是ABABBABA型的回文日期,通过观察可以发现a[i][0]=a[i][2],a[i][1]=a[i][3]。

for (i = 0; i < 365; i++)
	{
		if (a[i][0] == a[i][2] && a[i][1] == a[i][3])
		{
			s[i] = 1000 * a[i][0] + 100 * a[i][1] + 10 * a[i][2] + a[i][3] +
				10000 * a[i][0] + 100000 * a[i][1] + 1000000 * a[i][2] + 10000000 * a[i][3];
		}
		if (s[i] < 10011001)//最小的特殊回文日期
		{
			s[i] = 0;//确保存放的是八位数
		}
	}

然后在对s[i]进行遍历就可以得到答案。

for (i = 0; n >= s[i]; i++)
		;
	printf("%d\n", s[i]);

4.验证

蓝桥杯省赛真题——回文日期_第2张图片

蓝桥杯省赛真题——回文日期_第3张图片

你可能感兴趣的:(蓝桥杯,算法,职场和发展,c语言)