描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个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(2<=N<=10或N=16)
第二行为N进制数M(0<=M<=maxlongint)
输出格式
共一行
第一行为“STEP=”加上经过的步数或“Impossible!”
样例1
样例输入1
9
87
样例输出1
STEP=6
限制
各个测试点1s
来源
NOIP1999提高组第2题
思路
相比于直接使用加法再想办法转换进制,显然自己来实现加法更容易。
代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int isDone(int *, int); 6 void addYourAss(int *,int *,int); 7 8 int main() { 9 int radix,i,k,flag,cnt; 10 char c; 11 int a[100]; 12 // memset (a,0,sizeof(a)); 13 for (i=0;i<100;i++) { 14 a[i]=0; 15 } 16 k=0; 17 cnt=0; 18 flag=0; 19 scanf ("%d",&radix); 20 scanf ("%c",&c); 21 while (1) { 22 scanf ("%c",&c); 23 if (c==‘\n‘ || c==‘ ‘) break; 24 if (radix > 10 && c>‘9‘) { 25 a[k++]=c-55; 26 } 27 else { 28 a[k++]=c-48; 29 } 30 } 31 for (i=0;i<30;i++) { 32 if (isDone(a,k)) { 33 flag=1; 34 break; 35 } 36 else { 37 addYourAss(a,&k,radix); 38 // printf ("%d\n",k); 39 cnt++; 40 if (cnt>=30) { 41 break; 42 } 43 } 44 } 45 if (flag) { 46 printf("STEP=%d\n",cnt); 47 } 48 else { 49 printf ("Impossible!"); 50 } 51 system("pause"); 52 return 0; 53 } 54 55 int isDone(int *a,int len) { 56 int i,half; 57 half = len / 2; 58 for (i=0;i<half;i++) { 59 if (a[i]!=a[len-i-1]) { 60 return 0; 61 } 62 } 63 return 1; 64 } 65 66 void addYourAss(int *a,int *t,int radix) { 67 int b[100]; 68 int i; 69 for (i=0;i<*t;i++) { 70 b[i]=a[*t-i-1]; 71 } 72 for (i=0;i<*t;i++) { 73 a[i]+=b[i]; 74 if (a[i]>=radix) { 75 a[i]-=radix; 76 a[i+1]++; 77 } 78 } 79 if (a[*t]) { 80 (*t)++; 81 } 82 }