问题描述 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。 例如:给定一个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
记:
高精度计算,使用数组保存数据,防止溢出
AC代码:
1 #include <stdio.h> 2 #include <string.h> 3 #define MAX 10010 4 5 int n; /*进制数*/ 6 char m[MAX+1]; /*输入数*/ 7 int len = 1; /*输入数的长度*/ 8 int use[MAX+1] = {0}; 9 10 void init() 11 { 12 int i; 13 scanf("%d",&n); 14 scanf("%s",&m); 15 len = strlen(m); 16 for (i = 0 ; i < len ; i ++) 17 { 18 if (m[i]>= 48 && m[i]<=57) 19 { 20 use[i] = m[i]-48; 21 } 22 else 23 { 24 use[i] = m[i]-65+10; 25 } 26 } 27 return ; 28 } 29 30 void find(int x) 31 { 32 int i = 0 , j = len-1 , k = len/2; 33 int tmp[MAX+1] = {0}; 34 int carry = 0; /*进制位*/ 35 36 if (x > 30) 37 { 38 printf("Impossible!"); 39 return ; 40 } 41 42 /*回文判断*/ 43 while (k) 44 { 45 if (use[i] != use[j]) 46 { 47 break; 48 } 49 i ++,j --,k --; 50 } 51 52 if (i >= j) 53 { 54 printf("STEP=%d",x); 55 } 56 else 57 { 58 carry = 0; 59 for (i = 0 ; i < len ; i ++) 60 { 61 k = use[i]+use[len-1-i]+carry; 62 tmp[i] = k%n; 63 carry = k/n; 64 } 65 while (carry) 66 { 67 k = carry; 68 tmp[len] = k%n; 69 carry = k/n; 70 len ++; 71 } 72 for (i = 0 ; i < len ; i ++) 73 { 74 use[i] = tmp[i]; 75 } 76 find(x+1); 77 } 78 return ; 79 } 80 81 82 int main(void) 83 { 84 init(); 85 find(0); 86 return 0; 87 }