题目描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个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< =10或N=16)进制数M(其中16进制数字为0-9与A-F),求最少经过几步可以得到回文数。
如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”
输入格式
两行,N与M
N(2< =N< =10或N=16)
M最多不超过100位
输出格式
如果能在30步以内得到回文数,输出“STEP=xx”(不含引号),其中xx是步数;否则输出一行”Impossible!”(不含引号)
输入样例 复制
9
87
输出样例 复制
STEP=6
分类标签
#include <iostream>
#include<cstring>
#include <cstdio>
using
namespace
std;
int
main()
{
int
N,step=1;
char
M[100000];
cin>>N>>M;
loop:
int
a[100000],b[100000],result[100000],c=0;
int
carry=0,len=
strlen
(M);
for
(
int
i=0;i<len;i++){
if
(N==16){
if
(M[i]>=
'A'
&& M[i]<=
'F'
){
a[i]=M[i]-
'7'
;
}
else
{
a[i]=M[i]-
'0'
;
}
}
else
{
a[i]=M[i]-
'0'
;
}
}
for
(
int
i=0;i<len;i++){
b[i]=a[len-1-i];
/*求倒过来的数*/
}
for
(
int
i=0;i<len;i++){
/*所有位数通过for循环得到*/
int
temp=a[i]+b[i]+carry;
/*正数+倒数*/
result[c++]=temp%N;
/*余数*/
/*加而不加*/
carry=temp/N;
/*carry=进位*/
result[c]+=carry;
/*result【c】单个数位*/
/*进位*/
}
int
flag=1;
/*判断对错*/
if
(carry!=0)result[c++]=carry;
/*头部位置多了一位数*/
for
(
int
i=0;i<c/2;i++){
if
(step>=30){
flag=0;
/*判断是否超过30*/
cout<<
"Impossible!"
;
break
;
}
if
(result[i]!=result[c-1-i])
/*判断是否回文*/
{
step++;
for
(
int
i=0;i<c;i++){
if
(N==16){
if
(result[c-1-i]>=10){
M[i]=result[c-1-i]+
'7'
;
/*假如是16进制,则最终结果可以是字母*/
}
else
{
M[i]=result[c-1-i]+
'0'
;
}
}
else
{
M[i]=result[c-1-i]+
'0'
;
}
}
goto
loop;
}
}
if
(flag==1)cout<<
"STEP="
<<step;
return
0;
}