题目描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个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(100位之内),求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”
输入输出格式
输入格式:两行,分别是N,M。
输出格式:STEP=ans
输入输出样例
输入样例#1:
10 87
输出样例#1:
STEP=4
思路:暴力枚举30次,再仍上高精度加法(将mod 10 改成 mod N即可)。
注意事项:单纯思路有点简单了,说说要注意的地方吧,这题确实有一些地方会让人卡住。
1)注意读入后,将字符串数组转化为int型数组时,要考虑处理16进制数的情况,所以判断该字符是否是字母,若是,转化成10~15(16进制下的A~F)
2)最开始时要判断不需要头尾相加时就已经是回文数的情况。
#include<cstdio> #include<cstring> using namespace std; int n,len,a[11111],b[11111],c[11111]; bool jud(int *X) { for(int i=1;i<=len/2;i++) if(X[i]!=X[len-i+1])return 0; return 1; } void add_num() { int x=0; for(int i=1;i<=len;i++){ x+=a[i]+b[i]; c[i]+=x%n; x/=n; } while(x){c[++len]=x%n;x/=n;} } void solve() { if(jud(a)){puts("STEP=0");return;} for(int k=1;k<=30;k++){ memset(c,0,sizeof(c)); for(int i=1;i<=len;i++) b[i]=a[len-i+1]; add_num(); if(jud(c)){printf("STEP=%d ",k);return;} for(int i=1;i<=len;i++) a[i]=c[i]; } puts("Impossible!"); } int main() { char cr[111]; scanf("%d%s",&n,cr); len=strlen(cr); for(int i=0;i<len;i++){ if('0'<=cr[i]&&cr[i]<='9') a[len-i]=cr[i]-48; if('A'<=cr[i]&&cr[i]<='Z') a[len-i]=cr[i]-55; } solve(); return 0; }