【题目描述】
我们通常使用的都是十进制的数字,但其实在生活中也经常会使用其它进制。
这个题目会给你两个不同的数字,它们不属于同一进制,要求你计算出当它们分别处于何种进制之中时,两个数字相等。譬如 12 和 5 ,在十进制下它们是不等的,但若 12 使用 3 进制而 5 使用六进制或十进制时,它们的值就是相等的。因此只要选择合适的进制, 12 和 5 就可以是相等的。
程序的输入是两个数字 M 和 N( 其十进制的值不超过 1000000000) ,它们的进制在 2~36 之间。对于十以下的数字,用 0~9 表示,而十以上的数字,则使用大写的 A~Z 表示。
求出分别在 2~36 哪种进制下 M 和 N 相等。若相等则输出相应的进制,若不等则输出错误信息。当然了,对于多种可能成立的情况,找出符合要求的进制最小的一组就行了。信息的格式见测试用例。
Input1:
12 5↵
Output1:
12 (base 3) = 5 (base 6)↵
Input2:
123 456↵
Output2:
123 is not equal to 456 in any base 2..36↵
Input3:
10 A↵
Output3:
10 (base 10) = A (base 11)↵
Input4:
12 456↵
Output4:
12 is not equal to 456 in any base 2..36↵
【题目分析】
该题显然是一个字符串的题,稍加分析便知道不如假设一个数为a进制,一个数为b进制都转换为10进制,如果不相等再换a和b的值直到相等或a,b均大于32为止。该题所要做的操作便只有读入问题与将一个R进制数转换为一个10进制数,前者用万能的getchar()就可以解决(当然你需要知道什么是getchar()才行,比如它的参数是什么,返回值是什么,这个大家可以在任一一个网站上搜到,我在这里想强调的仅仅是getchar()的返回值是当前字符的ASCII码而已)
【C语言代码】
#include <stdio.h>
#include <string.h>
#define max(a,b) a>b?a:b
#define maxn 30
int x[maxn],y[maxn];
// 将一个长度为len的数字由n进制转化为10进制
int trans(int n,int len,int *c){
int ans=0;
for(int i=0;i<len;i++)
ans = ans*n+c[i];
return ans;
}
int main(){
char a[maxn],b[maxn];
//数组清空
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
scanf("%s %s",a,b);
int max1=0,max2=0,i,j;
// 存入每一位
for(i=0;;i++){
if(a[i]=='\0') {x[i]='\0'; break;}
if(a[i]>='0'&&a[i]<='9') x[i]=a[i]-'0';
else x[i]=a[i]-'A'+10;
max1=max(x[i],max1);
}
//将每一位由ASCII码转化为数字
for(j=0;;j++){
if(b[j]=='\0') {y[j]='\0'; break;}
if(b[j]>='0'&&b[j]<='9') y[j]=b[j]-'0';
else y[j]=b[j]-'A'+10;
max2=max(y[j],max2);
}
int len1=i,len2=j,flag=0;
//判断,用goto跳出双循环
for(i=max1+1;i<=32;i++){
for(j=max2+1;j<=32;j++){
if(trans(i,len1,x)==trans(j,len2,y)){
flag=1;
goto k;
}
}
}
k:
if(flag)
printf("%s (base %d) = %s (base %d)\n",a,i,b,j);
else
printf("%s is not equal to %s in any base 2..36\n",a,b);
return 0;
}
【Hint】
我在这代码里面用了很多可能没用过的操作,比如数组指针的传递,memset清空数组还有定义了一个宏函数,要注意的是一串数字中如果出现了k,那么这个数据至少是k+1进制的,所以我用这个思路可以降低部分计算量,让程序跑的比香港记者还快(暴力~)。比如一个数据是101,那么它至少是2进制的,再或者是A,那么它至少是A+1(也就是12进制)我们可以减少1/3的运算量。其实都从2开始循环也不会TLE的,只是这样做能跑得快一点。看不懂私聊找我吧,或者评论。