题解 | 回文数-NOIP1999普及组复赛B题
B-回文数_NOIP1999普及组复赛
https://ac.nowcoder.com/acm/contest/227/B
题目描述
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个10进制数56,将56加56(即把56从右向左读),得到121是一个回文数。
又如:对于10进制数87:
STEP1:87+78 = 165 STEP2:165+561 = 726
STEP3:726+627 = 1353 STEP4:1353+3531 = 4884
在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884。
写一个程序,给定一个进制数M,求最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible!”
输入描述:
两行,分别是N,M。
输出描述:
STEP=ans(ans表示答案)
示例1
输入
9
87
输出
STEP=6
解答
本题的解题思路大致是,先输入,随后进行存储(用十进制的方式),然后相加(注意进制问题last=a/n;a=a%n;)最后再判断是否回文即可,依次循环30次
代码如下:
#include<cstdio> #include<cctype> #include<cstring> #include<cstdlib> int n,a[2][100]; char s[100]; bool huiwen (int x)//如果一直相等,就返回1,一旦不相等就返回0 { int i,j=a[x][0]; for(i=1;i<j;i++,j--) if(a[x][i]!=a[x][j]) return 0; return 1; } void readdata() { int i,j,k; scanf("%d%s",&n,s); k=strlen(s); for(i=k-1;i>=0;i--) { if(isdigit(s[i]))j=s[i]-'0'; if(islower(s[i]))j=s[i]-'a'+10; //如果是字母,无论小写,大写,进行十进制存储 if(isupper(s[i]))j=s[i]-'A'+10; a[0][++a[0][0]]=j; //a[0][0]用来存储数字的位数,其后存储字符在十进制中的意思 } if(huiwen(0)) { printf("STEP=0\n"); exit(0); } } void add(int x) //x为1,0,1,0,1。。 { //y为0,1,0,1,0。。 int i,j,last,y=1-x; a[x][0]=a[y][0]; //a[y][0],表示数字的长度 last=0; for(i=1;i<=a[y][0];i++) { j=a[y][0]+1-i; a[x][i]=a[y][i]+a[y][j]+last; last=a[x][i]/n; a[x][i]%=n; } if(last>0) a[x][++a[x][0]]=last; } int main() { readdata(); for(int i=1;i<=30;i++) { add(i%2); //i为基数,add(1);huiwen(1); if(huiwen(i%2)) //i为偶数,add(0);huiwen(0); { printf("STEP=%d\n",i); return 0; } } printf("Impossible!\n"); return 0; }
来源:zmc1248234377