HUT1560 The Least Palindromic Number 模拟

1560: The Least Palindromic Number

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 111  Solved: 15
[Submit][Status][Web Board]

Description

    Palindromic numbers are digital strings that read the same both forwards and backwards. For example, 121, 44 and 3 are Palindromic numbers, 175, 36 are not;

    For a given integer N, you are to find a palindromic number P that satisfy P>N. However, there are many such palindromic numbers. Your task is to find the least one.

Input

    There are several test cases, each test case contains only one positive integer N in one line. The number of digits of N is not exceeding 10,000, and N has not lead zeroes.
    The input will finish with the end of file.

Output

    For each the case, your program will output the least palindromic number P (P > N) on separate line.

Sample Input

44
3
195

Sample Output

5
4
202

  这题数据解释一切 输入 101 111 1111 999  9999  1110 输出 111  121  1221  1001  10001  1111。这题一定要先分析清楚,不然写道后面代码量会增大,而且会存在漏洞。
  这题首先过滤掉特殊数据,那就是只有1位的数和全为9的数据,后面就要分长度为奇数和偶数进行分析,如果为奇数的,那么把串分两部分存储起来,从中间到两端进行比较,这样可以得到一个最接近的数,例如12345 先比较2 和 4, 如果前者比后者大,那么把前面的字符串反转存储到后面的数组中,再将中间的数以及反转后的数组连接到左边的数组上,如果前面的数比后面的数要小的话,那么就会复杂一点了,首先得判定中间的数是否为9,如果不为9的话,很好办,中间数加1再回到上面的情况,如果为9的话,就要进位了,有点类似大数中的进位,反正可以理解为将左边数组加上中间的数加上一个1,在第一种处理方式。长度为偶数的话就是不处理中间的数字就行了。还有一种情况就是如果该串左右对称那么可以将其归类到前面比后面小的那一类,不是吗?因为这里要求我们必须输出比原来要大的数。
  代码如下:
#include <stdio.h>
#include <string.h>

char num[10005], left[10005], right[10005];

void reverse( char *left, char *right, char center, int info )
{
	int len= strlen( left );
	for( int i= len- 1, j= 0; i>= 0; --i, ++j )
	{
		right[j]= left[i];
	}
	if( info )
	{
		left[len]= center, left[ len+ 1 ]= '\0';
	}
	strcat( left, right );
}

int main()
{
	while( scanf( "%s", num )!= EOF )
	{
		int len= strlen( num ), cnt= 0;
		for( int i= 0; i< len; ++i )
		{
			if( num[i]== '9' )
			{
				cnt++;
			}
		}
		if( cnt== len )
		{
			memset( num, '0', sizeof( num ) );
			num[0]= num[len]= '1';
			num[len+ 1]= '\0';
			puts( num );
			continue;
		}
		if( len== 1 )
		{
			if( num[0]< '9' )
			{
				printf( "%c\n", num[0]+ 1 );
				continue;
			}
			else
			{
				puts( "11" );
				continue;
			}
		}  // 以上为各种特殊处理
		int pos= len/ 2, flag= 0, kind;
		char center= num[pos];
		num[pos]= '\0';
		strcpy( left, num );            
		if( len& 1 )
		{
			kind= 1;
			strcpy( right, num+ pos+ 1 );
		}
		else
		{
			kind= 0;
			num[pos]= center;
			strcpy( right, num+ pos );
		}
		for( int i= pos- 1, j= 0; i>= 0; --i, ++j )
		{
			if( left[i]== right[j] )
			{
				if( i!= 0 )
				{
					continue;
				}
			}
			else if( left[i]> right[j] )
			{
				flag= 1;
				reverse( left, right, center, kind );
				break;
			}
			if( left[i]< right[j]|| i== 0 )
			{
				if( center!= '9'&& len& 1 )
				{
					center+= 1;
					reverse( left, right, center, kind );
					flag= 1;
					break;
				}
				else
				{
					center= '0';
					int i= pos- 1;
					left[i]+= 1;
					while( left[i]> '9' )
					{
						left[i]= '0';
						left[i- 1]+= 1;
						--i;
					}
					reverse( left, right, center, kind );
					flag= 1;
					break;
				}
			}
		}
		if( flag )
		{ 
			puts( left );
		}
	}
}

  其实这题应该可以直接用strcmp这个函数来比较的,那样还能简化很多操作。
原文地址:https://www.cnblogs.com/Lyush/p/2125428.html