1309:【例1.6】回文数(Noip1999)
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 18537 通过数: 7673
【题目描述】
若一个数(首位不为零)从左向右读与从右向左读都是一样,我们就将其称之为回文数。例如:给定一个 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.求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible” 。
【输入】
第1行,给定一个N(2<N≤10或N=16)表示进制;
第2行,一个N进制数M。
【输出】
最少几步。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible”。
【输入样例】
9
87
【输出样例】
6
因为是回文数,最高位就和最低位上的数相同,所以在做加法时(从右向左)即反转,可以
直接把数最高位定在串的后面就行
#include<bits/stdc++.h> using namespace std; int a[10005],b[10005],j; char c[1005]; int k;//长度用全局变量 int huiwen(int a[],int t)//判断回文数 { int i,j; for(i=0;i<t;i++)//t是串的长度 if((a[i])!=(a[t-1-i]))//前后全判断了 return 0; return 1; } void add1(int *q,int n)//加一次,数位是反转的 { for(int i=0;i<n;i++)//把a反转放在b串中 b[n-1-i]=*(q+i); for(int i=0;i<n;i++)//把a,b相应数位相加 *(q+i)+=b[i]; for(int i=0;i<n;i++)//用进制除,高位进,低位取模 因为是反转的数位,可把0看作个位了(因为是回文,最高位也得等于最低位) { *(q+i+1)+=*(q+i)/j; *(q+i)=*(q+i)%j; } if(*(q+n)>0)//最后,如果还有进位,长度加1 k++; } int main() { int i; scanf("%d",&j);// 进制 scanf("%s",c);//数,字串形式 k=strlen(c);//求出长度 for(i=0;i<k;i++) { //转换为整形的串 a[i]=c[i]; if(a[i]>='0'&&a[i]<='9')//对于那么小于等于9的数 a[i]-='0'; else//如果是10进制以上的到16进制的数时 a[i]=a[i]-'A'+10;//就有10几来表示 } if(huiwen(a,k))//如果本身就是回文数 { printf("0"); return 0; } i=0; while(i<=30)//做30次的计算 { i++; add1(a,k);//做一次加法计算 if(huiwen(a,k))//是回文数,输出 { printf("%d",i); return 0; } } printf("Impossible");//30次后还不是回文数 return 0; }