时间限制1.00s 内存限制125.00MB 难易度:普及−
【题目描述】
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个十进制数 56,将 56 加 65(即把 56 从右向左读),得到 121 是一个回文数。
又如:对于十进制数 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=1)进制数 M(100 位之内),求最少经过几步可以得到回文数。如果在 30 步以内(包含 30 步)不可能得到回文数,则输出 Impossible!
。
【输入格式】
两行,分别是 N,M。
【输出格式】
如果能在 30 步以内得到回文数,输出格式形如 STEP=ans
,其中 ans 为最少得到回文数的步数。
否则输出 Impossible!
。
【输入输出样例】
输入 #1
10 87
输出 #1
STEP=4
【算法分析】
这道题,我们需要转换进制,高精计算和判断回文,简直转换需要将字符转为数字在转回字符(详见代码),高精计算用字符串代表数,回文的判断只需正反遍历查看是否相等即可。
【参考代码】
#include <bits/stdc++.h>
using namespace std;
int n,ans=0,t=0;
string m;
bool hw(string s) //回文判断函数。
{
int len=s.size();
for(int i=0;i<len/2;i++)
if(s[i]!=s[len-1-i])return false;
return true;
}
int jzzh(char x) //将字符转成数字(为了进制转换)。
{
if(x>='0'&&x<='9') return int(x-48);
else //16进制。
{
if(x=='A') return 10;
if(x=='B') return 11;
if(x=='C') return 12;
if(x=='D') return 13;
if(x=='E') return 14;
if(x=='F') return 15;
}
}
char jzzh2(int x) //将数字转回字符
{
if(x>=0&&x<=9) return char(x+48);
else
{
if(x==10) return char('A');
if(x==11) return char('B');
if(x==12) return char('C');
if(x==13) return char('D');
if(x==14) return char('E');
if(x==15) return char('F');
}
}
string add(string a,string b) //加法。
{
int len=b.size();
for(int i=0;i<len/2;i++) //进行反转。
swap(b[i],b[len-1-i]);
string sum;
int jw=0,aw=0,bw=0,cw=0;
for(int i=a.size()-1;i>=0;i--)
{
aw=jzzh(a[i]); //将a[i]转成数字。
bw=jzzh(b[i]); //将b[i]转成数字。
cw=(aw+bw+jw)%n;
if(aw+bw+jw>=n)jw=1; //判断是否进位。
else jw=0;
sum=jzzh2(cw)+sum; //将这一位的数转回字符放在c字符串。
}
if(jw==1)sum='1'+sum; //不要忘记最后一位还会进位。
return sum;
}
int main()
{
cin>>n>>m;
while(t==false)
{
if(ans>30) //如果在30步以内不能得到回文数,输出"Impossible!"。
{
cout<<"Impossible!";
return 0;
}
ans++; //计步。
m=add(m,m); //计算。
t=hw(m); //判断回文。
}
cout<<"STEP="<<ans;
return 0;
}