问题 G: 回文数
时间限制: 1 Sec 内存限制: 256 MB提交: 178 解决: 54
[ 提交][ 状态][ 讨论版]
题目描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个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!”
例如:给定一个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。
输出
如果能在30步以内得到回文数,输出“STEP=xx”(不含引号),其中xx是步数;否则输出一行”Impossible!”(不含引号)
样例输入
9
87
样例输出
STEP=6
#include<bits/stdc++.h>
#define M(a,b) memset(a,b,sizeof(a))
#define maxn 1000
using namespace std;
char str[maxn];
int A[maxn];
int B[maxn];
int C[maxn];
int n;
int getpos()
{
int l=maxn;
while(A[l]==0)l--;
return l;
}
/*void Print(int *a)
{
for(int i=0;i<=getpos();i++)
{
cout<<A[i];
}
cout<<endl;
}*/
bool judge()
{
int i=0;
int j=getpos();
while(i<j)
{
if(A[i]!=A[j])
{
return false;
}
i++;
j--;
}
return true;
}
void work( )
{
int len=getpos();
for(int k=0;k<=len;k++)
{
B[k]=A[len-k];
C[len-k]=A[len-k];
}
int j=0;
int jw=0;
for(int i=0;i<=len;i++)
{
A[i]=(C[i]+B[i]+jw)%n;
jw=(C[i]+B[i]+jw)/n;
}
if(jw)
{
A[len]=A[len]%n;
A[len+1]=jw;
}
}
int main()
{
while(cin>>n>>str)
{
M(A,0);
M(B,0);
M(C,0);
int len=strlen(str);
int j=0;
for(int i=len-1;i>=0;i--)
{
if(str[i]>=65)
A[j++]=str[i]-55;
else
A[j++]=str[i]-'0';
}
int f=1;
if(judge())printf("0\n");
else{
for(int i=1;i<=30;i++)
{
work();
if(judge())
{
f=0;
cout<<"STEP="<<i<<endl;
break;
}
}
if(f)cout<<"Impossible!"<<endl;
}
}
}