我的想法很朴素,就是分奇偶情况讨论。
#include <stdio.h>
#include <string.h>
char s[509];
int len;
int compare()
{
int mid = len / 2;
int i, j;
for (i = mid - 1, j = mid + 1; i >= 0; i--, j++)
{
if (s[i] > s[j])
{ // 前大于后
return 0;
}
else if (s[i] < s[j])
{ // 后大于前
return 1;
}
}
return -1; //-1表明其本身即是回文数
}
int compare2()
{
int mid = len / 2 - 1;
int i, j;
for (i = mid, j = mid + 1; i >= 0; i--, j++)
{
if (s[i] > s[j])
{ // 前大于后
return 0;
}
else if (s[i] < s[j])
{ // 后大于前
return 1;
}
}
return -1; //-1表明其本身即是回文数
}
int search(int i)
{
for (int tem = i; tem >= 0; tem--)
{
if (s[tem] != '0')
{
s[tem] = ((s[tem] - '0') - 1) + '0';
return tem;
}
else
{
s[tem] = '9';
}
}
return -1;
}
int main()
{
int T;
scanf("%d", &T);
for (int time = 0; time < T; time++)
{
scanf("%s", s);
len = strlen(s);
if (len & 1 == 1)
{ // 奇数
int judge = compare();
if (judge == -1)
{ // 其本身
printf("%s\n", s);
continue;
}
else if (judge == 1)
{ // 只修改奇数后半部分
int k;
for (k = 0; k <= len / 2; k++)
{
printf("%c", s[k]);
}
for (k = len / 2 - 1; k >= 0; k--)
{
printf("%c", s[k]);
}
printf("\n");
continue;
}
else
{ // 需要向前查找第一个非0的数
int pos = search(len / 2);
if (s[pos] == '0' && pos == 0)
{
for (int tem = 1; tem < len; tem++)
{
printf("9");
}
printf("\n");
}
else
{ // 输出
for (int tem = 0; tem <= len / 2; tem++)
{
printf("%c", s[tem]);
}
for (int tem = len / 2 - 1; tem >= 0; tem--)
{
printf("%c", s[tem]);
}
printf("\n");
}
}
}
else
{ // 偶数
int judge = compare2();
if (judge == -1)
{ // 其本身
printf("%s\n", s);
continue;
}
else if (judge == 1)
{
int k;
for (k = 0; k <= len / 2 - 1; k++)
{
printf("%c", s[k]);
}
for (k = len / 2 - 1; k >= 0; k--)
{
printf("%c", s[k]);
}
printf("\n");
continue;
}
else
{ // 需要向前查找第一个非0的数
int pos = search(len / 2 - 1);
if (s[pos] == '0' && pos == 0)
{
for (int tem = 1; tem < len; tem++)
{
printf("9");
}
printf("\n");
}
else
{ // 输出
for (int tem = 0; tem <= len/2-1; tem++)
{
printf("%c", s[tem]);
}
for (int tem = len/2-1; tem >= 0; tem--)
{
printf("%c", s[tem]);
}
printf("\n");
}
}
}
}
return 0;
}
之后,看到肖同学的方法很不错,在此记录一下。
根据回文数的性质,我们不难想到:
对于一个形如 ABCDEFGH 的整数
有且仅有一个比它大的最小回文数
有且仅有一个比它小的最大回文数
ABCDDCBA 一定是其中之一
例如:
36763是比36720大的最小回文数
90109是比90135小的最大回文数
所以对于本题,可以得出结论:
输入 ABCD ,若ABBA 比 ABCD 小,则 ABBA 就是比她小的最大回文数,然后就可
以直接输出这个答案了。
(即将原串的前一半,复制到后一半)
但是我们不能保证ABBA一定比ABCD小
如果ABBA比ABCD大,那就要找比ABBA小的前一个回文数了
比如51412,按照上述操作得到51415,然而她大于了原来的数,就要找比她小的一个数,答案应该是51315
再举几个例子
输入398427,按照”ABBA”的想法得到398893,大了,重找,是397793
输入39023,按照”ABBA”的想法得到39093,大了,重找,是38983
输入2000001,按照”ABBA”的想法得到2000002,大了,重找,是1999991
…………
可以看到,当“ABBA”大于原数的时候,我们为了找一个比原数小的数,要把中间位置减1,如果中间是0,就往前借位,同时0变成9
(为啥是中间位置呢?因为我们要保证这个数是最大数)
最后,需要注意一下特殊情况
比如1000的回文数,应该是999
按照“ABBA”的思想,得到1001,显然大了
但是这里再去减,会出现第一位是0的情况
因此类似10^k这种情况
我们特判一下就好
即这种情况下,答案就是k个9