题目描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个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();
}