题目大致翻译后就是说:如果一个数不是回文数的话,有方法可以将他转变为回文数,转变的方法是:将这个数与这个数的倒序相加,如果仍不是回文数,则重复该过程。
具体例子:67 + 76 = 143, and 143 + 341 = 484.
就是将67经过两步转变为回文数484。
题目的要求是,输入一个数(这个数很大,long long 肯定也要溢出)和k,在k步以内,如果可以将这个数变为回文数,则输出最终的回文数以及经过的步骤数,否则输出已经求得的数与k。
这个题主要就是考虑大数加法。
直接上源码分析:
#include<iostream>
#include<string>
using namespace std;
bool is_number(string s) //判断这个数是否是回文数
{
for (int i = 0; i <=int(s.size())/2; i++)
if (s[i] != s[s.size() - 1 - i])
return 0;
return 1;
}
//写了一个内联函数,免得使代码看起来很乱
inline int transfer(char a)
{
return int(a - '0');
}
//大数加法
string addstring(string& s)
{
string temp = s;
for (int i = 0; i <int(s.size()) ; i++)
temp[i] = s[int(s.size()) - i - 1];
//temp就是s的倒序
int length = int(s.size());
bool overflow = 0; //溢出标志
for (int i = 0; i < length; i++)
{
int result =
transfer(s[length - 1 - i]) + transfer(temp[length - 1 - i]);
//进行加法
//判断进位从倒数第二位开始
if (overflow && i > 0)
result++; //如果溢出结果加一
if (result < 10) //没溢出 则直接赋值
{
s[length - 1 - i] = '0' + result;
overflow = 0;
}
else //溢出则稍加处理
{
overflow = 1;
s[length - 1 - i] = '0' + result - 10;
}
}
//这里是为了判断最高位有没有进制 有进制则也要加1
if (overflow)
s = '1' + s;
return s;
}
// 重复加法
void add(string s, int k)
{
//k是重复的上限
if (is_number(s))
{
cout << s << "\n" << 0;
return;
}//如果一开始就是回文数 则根本不用进行加法
int times = 0; //统计加法的次数
for (int i = 0; i < k; i++)
{
s = addstring(s); //开始进行加法
times++;
if (is_number(s)) //如果是回文数 就输出吧!
{
cout << s << "\n" << times;
return;
}
}
cout << s << "\n" << k;
}
int main()
{
string s;
int k;
cin >> s >> k;
add(s, k);
}
这个题 也没有遇到什么bug就AC了,哈哈哈哈,可能是运气比较好。