PAT 1024 Palindromic Number (25分) 使用string类reverse()
题目
A number that will be the same when it is written forwards or backwards is known as a Palindromic Number. For example, 1234321 is a palindromic number. All single digit numbers are palindromic numbers.
Non-palindromic numbers can be paired with palindromic ones via a series of operations. First, the non-palindromic number is reversed and the result is added to the original number. If the result is not a palindromic number, this is repeated until it gives a palindromic number. For example, if we start from 67, we can obtain a palindromic number in 2 steps: 67 + 76 = 143, and 143 + 341 = 484.
Given any positive integer N, you are supposed to find its paired palindromic number and the number of steps taken to find it.
Input Specification:
Each input file contains one test case. Each case consists of two positive numbers N and K, where N (≤1010 ) is the initial numer and K (≤100) is the maximum number of steps. The numbers are separated by a space.
Output Specification:
For each test case, output two numbers, one in each line. The first number is the paired palindromic number of N, and the second number is the number of steps taken to find the palindromic number. If the palindromic number is not found after K steps, just output the number obtained at the Kth step and K instead.
Sample Input 1:
67 3
Sample Output 1:
484
2
Sample Input 2:
69 3
Sample Output 2:
1353
3
题目解读
像 1234321
这种左右对称的数字称为 palindromic number
,但是一个非回文数可以经过转换得到一个回文数:反转自己,自己加上反转后的自己,得到新的数。重复这个过程,知道得到的数字是一个回文数。
给你一个非回文数字N
和最大转换次数K
,让你计算把它转为一个回文数字需要几步,输出 最终得到的回文数和转换次数;如果经过了K次转换后得到的还不是一个回文数,那么就输出 第K
次转换的结果和K
。
思路分析
这个题目没什么难度,就重复这个过程:
- 判断是否回文
- 若是回文数或者转换次数达到上限就输出结果
- 若不是回文数就反转自己,自己加上反转后的自己,转换次数+1
我们只需要考虑,如何存储这个数字,如何判断回文,如何反转就好:
- 如何存储,题目说了
N
最大为1010,转换次数最多为100,所以int
会溢出,我们可以考虑char[]
或者string
; - 因为要反转,所以选择
string s
,reverse(s.begin(), s.end());
一步搞定,所以long
和long long
我们也没有考虑。 - 求和,本来两个数相加需要右对齐,然后从右往左对应位置数字相加,保留%10的数字,如有进位就向前进位。但是现在
s + t
,t
是s
的reverse()
,所以对齐不用考虑,也不用从右往左,就从左往右,345 + 543
和543 + 345
没啥区别啊,但是有个地方要注意,如果是从左往右相加,最终的进位就进到最右面去了,但实际上进位方向是要想左,所以我们最终要再反转一下才能得到结果。
问题解决完了我们来看代码吧
最终代码
因为 s
一直要改变,所以直接用一个全局 string s
存储即可。
#include <iostream>
#include <algorithm>
using namespace std;
// 题目说N的长度 <= 10,所以int 和 longlong 都无法存储,而且反转不好处理
// 用字符串
// 这个数字一直在增加,所以用全局变量保存
string s;
// 计算 s + s.reverse()
// 因为 t 是 s 反转得到的,所以 正着加和倒着加没什么区别,只需要最后再反转一次就好
void add(string t) {
int len = s.length();
// 进位
int carry = 0;
for (int i = 0; i < len; ++i) {
// int n1 = s[i] - '0', n2 = t[i] - '0'
// sum = n1 + n2 + carry
// s[i] = sum % 10 + '0'
// carry = sum / 10
s[i] = s[i] + t[i] + carry - '0';
carry = 0;
if (s[i] > '9') {
// 如果有进位
s[i] = s[i] - 10;
carry = 1;
}
}
// 不要忘了最高位的进位
if (carry) s += '1';
// 最后结果要反转
reverse(s.begin(), s.end());
}
int main() {
int k, i;
cin >> s >> k;
// 进行一次逆转和求和才是一次处理过程,所以i从0开始
for(i = 0; i <= k; i++) {
string t = s;
reverse(t.begin(), t.end());
// 这个数是palindromic,或 达到最大转换次数
if (t == s || i == k) break;
add(t);
}
// 输出结果
cout << s << endl << i;
return 0;
}