题目描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个十进制数 56,将 56 加 65(即把 56 从右向左读),得到 121 是一个回文数。
又如:对于十进制数 87:
STEP1:87+78=165
STEP2:1165+561=726
STEP3:726+627=1353
STEP4:1353+3531=4884
在这里的一步是指进行了一次 N 进制的加法,上例最少用了 4 步得到回文数 4884。
写一个程序,给定一个 N(2≤N≤10 或 N=16)进制数 M(100 位之内),求最少经过几步可以得到回文数。如果在 30 步以内(包含 30 步)不可能得到回文数,则输出 Impossible!
。
输入格式
两行,分别是 N,M。
输出格式
如果能在 30 步以内得到回文数,输出格式形如 STEP=ans
,其中ans 为最少得到回文数的步数。
否则输出 Impossible!
。
输入输出样例
输入 #1
10 87
输出 #1
STEP=4
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
// 判断一个字符串是否是回文数
bool isPalindrome(const string &s) {
int left = 0, right = s.size() - 1; // 初始化左右指针
while (left < right) { // 当左指针小于右指针时循环
if (s[left] != s[right]) { // 如果左右指针指向的字符不相等
return false; // 返回false,表示不是回文数
}
left++; // 左指针右移
right--; // 右指针左移
}
return true; // 返回true,表示是回文数
}
// 将字符串表示的N进制数反转
string reverseString(const string &s) {
string rev = s; // 复制原字符串
reverse(rev.begin(), rev.end()); // 反转字符串
return rev; // 返回反转后的字符串
}
// 将字符串表示的N进制数转换为整数
int charToDigit(char c) {
if (c >= '0' && c <= '9') return c - '0'; // 如果是数字字符,返回对应的整数
if (c >= 'A' && c <= 'F') return c - 'A' + 10; // 如果是字母字符,返回对应的整数
return -1; // 错误情况
}
// 将整数转换为字符
char digitToChar(int d) {
if (d >= 0 && d <= 9) return '0' + d; // 如果是0-9的整数,返回对应的字符
if (d >= 10 && d <= 15) return 'A' + (d - 10); // 如果是10-15的整数,返回对应的字符
return '0'; // 错误情况
}
// 进行N进制数的加法
string addInBaseN(const string &a, const string &b, int base) {
string result; // 存储结果的字符串
int carry = 0; // 进位初始化为0
int i = a.size() - 1, j = b.size() - 1; // 初始化两个字符串的末尾索引
while (i >= 0 || j >= 0 || carry) { // 当索引大于等于0或者进位不为0时循环
int sum = carry; // 当前位的和初始化为进位
if (i >= 0) sum += charToDigit(a[i--]); // 如果a的索引有效,加上a的当前位
if (j >= 0) sum += charToDigit(b[j--]); // 如果b的索引有效,加上b的当前位
carry = sum / base; // 计算新的进位
result.push_back(digitToChar(sum % base)); // 将当前位的结果添加到结果字符串中
}
reverse(result.begin(), result.end()); // 反转结果字符串,使其正确排列
return result; // 返回结果字符串
}
int main() {
int N; // 进制数
string M; // 输入的N进制数
cin >> N >> M; // 读取输入
for (int step = 1; step <= 30; ++step) { // 循环最多30次
string reversedM = reverseString(M); // 反转M
string sum = addInBaseN(M, reversedM, N); // 计算M和反转M的和
if (isPalindrome(sum)) { // 如果和是回文数
cout << "STEP=" << step << endl; // 输出步数
return 0; // 结束程序
}
M = sum; // 更新M为新的和
}
cout << "Impossible!" << endl; // 如果在30步内没有找到回文数,输出Impossible!
return 0; // 结束程序
}