題目描述
若一個數(首位不爲零)從左向右讀與從右向左讀都一樣,我們就將其稱之爲迴文數。
例如:給定一個10進制數56,將56加65(即把56從右向左讀),得到121是一個迴文數。
又如:對於10進制數87:
STEP1:87+78 = 165 STEP2:165+561 = 726
STEP3:726+627 = 1353 STEP4:1353+3531 = 4884
在這裏的一步是指進行了一次N進制的加法,上例最少用了4步得到迴文數4884。
寫一個程序,給定一個N(2<=N<=16)進制數M,求最少經過幾步可以得到迴文數。如果在30步以內(包含30步)不可能得到迴文數,則輸出“Impossible!”
輸入
共兩行
第一行爲進制數N(2<=N<=16)
第二行爲N進制數M(0<=M<=maxlongint)
輸出
共一行,爲“STEP=經過的步數”或“Impossible!”
樣例輸入
9
87
樣例輸出
STEP=6
解題思路
主要分爲兩步;
一,正逆相加
有兩種方法進行相加;
直接相加的過程就按照n進制相加。
int q,w=0; //先定義q,w。
for(int p=1;p<=i;p++)
{
q=(a[p]+a[i-p+1]+w)%n; //q存本次相加後的餘數,然後直接存到數組b中
w=(a[p]+a[i-p+1]+w)/n; //w存本次相加後的商,也就是進制,加到下次的運算中。
b[p]=q;
if(w!=0 && p==i) //當p到最後一個數且還要進位時,i++,b【i】=w,然後退出
{
i++;
b[i]=w;
break;
}
}
先按十進制相加存到數組b中,然後再將數組b按n進制返回到a中
for (int t = 1; t <= i; t++)
{
b[t] = a[t] + a[i - t + 1]; //首尾相加 //先按照十進制相加,然後存到數組b中
}
for (int t = 1; t <= i; t++)
{
if (b[t] >= n) //多少進制就大於等於多少,就減去多少進位,將10進制轉換爲n進制
{
b[t] = b[t] - n;
b[t + 1] = b[t + 1] + 1; //進入if語句即表示超過進制,所以下一位直接加一
if (t == i) i++; //最後一個要是超出了n,那麼再給多一個下標保存,便於判斷
}
}
二,判斷是否迴文
代碼
#include<iostream>
using namespace std;
int main()
{
long n, m;
cin >> n;
cin >> m;
int a[1000] = { 0 };
int b[1000] = { 0 };
long i = 0;
long x = 0;
while (m) //以n進制存入數組
{
x = m % 10;
i++;
a[i] = x;
m = m / 10;
}
int y = 0; //判斷迴文
int yy = 0; //判斷次數
while (y == 0)
{
第一種方法:
int q,w=0;
for(int p=1;p<=i;p++)
{
q=(a[p]+a[i-p+1]+w)%n; //q存本次的餘數
w=(a[p]+a[i-p+1]+w)/n; //w存商,加到下一次中
b[p]=q;
if(w!=0 && p==i) //當p到最後一個數且還要進位時
{
i++;
b[i]=w;
break;
}
}
第二種方法
for (int t = 1; t <= i; t++)
{
b[t] = a[t] + a[i - t + 1]; //首尾相加
}
for (int t = 1; t <= i; t++)
{
if (b[t] >= n) //多少進制就大於等於多少,就減去多少進位
{
b[t] = b[t] - n;
b[t + 1] = b[t + 1] + 1;
if (t == i) i++; //最後一個要是超出了n,那麼再給多一個下標保存,便於判斷
}
}
for (int p = 1; p <= i; p++)
{
a[p] = b[p];
}
for (int j = 1; j <= i / 2; j++)
{
if (a[j] != a[i - j + 1])
{
y = 1;
break;
}
}
yy++;
if (yy > 30)
{
cout << "Impossible!" << endl;
break;
}
if (y == 0)
{
cout << "STEP=" << yy << endl;
break;
}
y = 0;
}
getchar();
getchar();
}