原题链接:回文数(二)
解题思路:
首先,看输入数据的取值范围,二进制最大长整型数,若需要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、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复