Vijos p1304 回文數
阿新 • • 發佈:2018-02-27
+= 輸入 進行 nbsp style pan blog memset print
描述
若一個數(首位不為零)從左向右讀與從右向左讀都一樣,我們就將其稱之為回文數。
例如:給定一個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 5int 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 }
Vijos p1304 回文數