原题链接:回文数(二)
解题思路:
首先,看输入数据的取值范围,二进制最大长整型数,若需要8字节就是64位,只能作为字符串读取。观察每步操作,归纳为两个函数,一个将数值取反,另一个求两个N进制数相加的结果。
注意事项:
对于N进制,若N大于10、小于等于16,在两个N进制数相加时,数字10~15用单个字符表示,取值范围是a~f或A~F。
参考代码:
#include<stdio.h> #include<string.h> int N; int main(){ void rev(int,const char [],char []); int add(int,const char [],const char [],char []); char M[100],R[100],A[100],B[100]; int m,n,s=30; scanf("%d",&N); scanf("%s",M); //N进制数M作为字符串输入 while(s--){ //只考察30步以内能得到回文数 m=strlen(M); rev(m,M,R); //将长度为m的串M反向保存到串R n=add(m,M,R,A); //A=M+R,返回A的长度保存到n rev(n,A,B); //把A从右向左读得到B if(!strcmp(A,B)){ //若A和B相等 printf("STEP=%d",30-s); //经过30-s步找到回文数 break; } strcpy(M,A); //将上一步的和保存到M继续下一步 } if(s<0) printf("Impossible!"); //30步以内未找到回文数 return 0; } void rev(int x,const char a[],char b[]){ int i; for(i=0;i<x;i++) b[x-i-1]=a[i]; //将a的内容反向保存到b b[x]='\0'; } int add(int n,const char a[],const char b[],char c[]){ int i,x,y,z,j=0; char t[100]; for(i=0;i<n;i++){ //逐位取值相加进位 if(a[i]>='0'&&a[i]<='9') x=a[i]-'0'; //a[i]数字 else if(a[i]>='A'&&a[i]<='F') x=a[i]-'A'+10;//a[i]大写 else if(a[i]>='a'&&a[i]<='f') x=a[i]-'a'+10;//a[i]小写 if(b[i]>='0'&&b[i]<='9') y=b[i]-'0'; //b[i]若为数字对应的数值 else if(b[i]>='A'&&b[i]<='F') y=b[i]-'A'+10;//b[i]若为大写字母对应的数值 else if(b[i]>='a'&&b[i]<='f') y=b[i]-'a'+10;//b[i]若为小写字母对应的数值 z=(x+y+j)%N; //加进位,当前位在N进制内的数值 if(z<10) t[i]=(char)z+'0'; //数值小于10保存为数字字符 else t[i]=(char)(z-10)+'a'; //数值超过10保存为字母字符 j=(x+y+j-z)/N; //j向高位进位 } if(j>0){ //j向最高位进位 t[n]=(char)j+'0'; //保存最高位的字符 t[n+1]='\0'; rev(n+1,t,c); //反向保存结果 return n+1; //返回结果的位数 }else if(!j){ //j未向最高位进位 t[n]='\0'; rev(n,t,c); return n; //结果长度不变 } }
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复