回文数(进阶版)

若一个数(首位不为零)从左向右读与从右向左读都是一样,我们就将其称之为回文数。例如:给定一个 10进制数 56,将 56加 65(即把56从右向左读),得到 121是一个回文数。又如,对于10进制数87,

STEPl: 87+78= 165         STEP2: 165+561= 726

STEP3:726+627=1353  STEP4:1353+3531=4884   

在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。   

写一个程序,给定一个N(2<N<=10或N=16)进制数 M.求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”

输入

输入一行两个整数N和M

输出

如果能在30步以内得到回文数,输出最少得到回文数的步数。

否则输出 Impossible!

样例输入 Copy
9   87
样例输出 Copy
6
提示

2<N<=10或N=16

M的位数在100位以内

提交

#include
using namespace std;
const int maxN = 105;
char sixt[20] = "0123456789ABCDEF";
int n;
string m;
bool hw(string a) {
    string s = a;
    reverse(s.begin(), s.end());
    return s == a; 
}
string add(int k, string b) { 
    string a = b;
    reverse(a.begin(), a.end());
    int numa[maxN], numb[maxN], numc[maxN];
    int len = a.length(), lenc = 1;
    string ans;
    for (int i=0; i         if (isdigit(a[i])) numa[len-i] = a[i] - '0'; 
        else numa[len-i] = a[i] - 'A' + 10;
        if (isdigit(b[i])) numb[len-i] = b[i] - '0';
        else numb[len-i] = b[i] - 'A' + 10;
    }
    int x = 0;
    while (lenc <= len) {
        numc[lenc] = numa[lenc] + numb[lenc] + x;
        x = numc[lenc] / k; 
        numc[lenc] %= k;
        lenc++;
    }
    numc[lenc] = x;
    while (numc[lenc] == 0) lenc--;
    for (int i=lenc; i>=1; i--) ans += sixt[numc[i]];
    return ans;
}
int main() {
    cin >> n >> m;
    for (int i=0; i<=30; i++){
        if(hw(m)) {
            printf("%d", i);
            return 0;
        }
        else m = add(n, m);
    }
    printf("Impossible!"); 
    return 0;
}
 

你可能感兴趣的:(算法)