题目如下:
这道题的解答思路:
1、因为 n 过于大,所以用字符串来存,基本方法是将尾字符改为首字符,然后不断循环,这样就能构成回文了。 (例如: 1234 改为 1221)
2、因为所得到的数不能大于 n ,所以考虑若尾字符大于首字符,就无法直接赋值,要把尾字符前一个字符减一,再赋值。 (例如: 5432 要借位改为 5335)
3、若在 2 的情况下,前一个字符为‘ 0 ’,那么就不能直接减一(因为不能为-1),所以就要把尾字符前连续的0都干掉(如果只解决一个0,那么有多个0的情况还是会错),就是用一个循环,如果尾字符前一个字符为0,就将它改为9,遍历到非0位置停止,并将此位置的数字减一。 (例如: 5004 遇到0 按上方法改为 4994)
4、在3的情况下可能会遇到(1000)的情况,所以干脆从一开始就判断一次尾字符为0的情况,按照3方法清除,若第1个字符(首字符)为0,则把它删除。 (例如: 1000 更新为 999 再套上述方法, 1100 则更新为1099, 再套上述方法)
下面就是我通过的代码:
#include<bits/stdc++.h>
#include<string>
using namespace std;
int main( )
{
string s;//1所写的:n的范围是1到10的200次方,太大了所以用字符串存储
cin >> s;
while(s[0] == '0')//干掉前面的0
s.erase(0, 1);
int begin = 0, end = s.size() - 1;
//这是 4 所写的,尾字符为0情况,更新字符串
if(s[end] == '0')
{
int tmp = end;
while(s[tmp] == '0')
{
s[tmp--] = '9';//0 改为 9
}
s[tmp]--;// 结束后非0位置-1
if(s[tmp] == '0' && tmp == 0)//如果首字符为0,干掉它
{
s.erase(0, 1);
--end;
}
}
//正式开始判断,是2,3所说的
while(begin < end)
{
if(s[end] < s[begin])//如果尾字符大于首字符,就执行2
{
if(s[end - 1] == '0')//如果前一位为0,执行3
{
int tmp = end - 1;
while(s[tmp] == '0')
{
s[tmp--] = '9';
}
s[tmp]--;
}
else
{
s[end - 1]--;
}
}
s[end--] = s[begin++];//更新完成后正常遍历
}
cout << s;
return 0;
}