Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is yes
, if 6 is a decimal number and 110 is a binary number.
Now for any pair of positive integers N1 and N2, your task is to find the radix of one number while that of the other is given.
Each input file contains one test case. Each case occupies a line which contains 4 positive integers:
N1 N2 tag radix
Here N1
and N2
each has no more than 10 digits. A digit is less than its radix and is chosen from the set { 0-9, a-z } where 0-9 represent the decimal numbers 0-9, and a
-z
represent the decimal numbers 10-35. The last number radix is the radix of N1
if tag
is 1, or of N2
if tag
is 2.
For each test case, print in one line the radix of the other number so that the equation N1
= N2
is true. If the equation is impossible, print Impossible
. If the solution is not unique, output the smallest possible radix.
6 110 1 10
2
1 ab 1 2
Impossible
本题难度不大,但是有几个测试点比较难以通过,需要注意的点是:
adc
,那么该数字的基数至少为13。上界限的定义比较复杂:首先上界限一定是大于下界限的,其次上界限最多为目标数字的大小+1,比如另一个数字是99,那么上界限最多为99,因为要判断的数的基数一旦大于目标数,不可能与这个数相同input:
9999999999 9999999999 1 10
output:
10
input:
12 c 1 10
output:
13
input:
99 10 1 10
output:
99
input:
0 0 1 10
output:
2
首先需要定义一个将一个字符串根据基数转化为十进制数的函数:
就是简单的累加
long long number_to_ten(char *a,long long radix)//calculate the number of char with radix
{
long long sum=0,len=strlen(a),mul=1;
for(int i=len-1;i>=0;i--)
{
if(a[i]>='0'&&a[i]<='9')
{
if(a[i]-'0'>=radix)return 0;
sum+=(a[i]-'0')*mul;
}
else
{
if(a[i]-'a'+10>=radix)return 0;
sum+=(a[i]-'a'+10)*mul;
}
mul*=radix;
}
return sum;
}
其次要定义根据目标数查找基数的函数:
在这个函数中,分为两步:
注意题目中说,如果存在多个基数满足结果,输出的应该是可能的最小基数,因此在二分查找中,如果一旦中间值满足条件,应该把上界设为中间值,只有在中间值满足条件,且下界也满足条件,返回下界值
long long find_radix(char* a,long long equal)
{
//定义上下界
long long min_radix=2,max_radix;
long long radix;
for(int i=0;i<strlen(a);i++)//find the min base
{
if(a[i]>='0'&&a[i]<='9')
{
min_radix=min_radix>(a[i]-'0')?min_radix:(a[i]-'0'+1);
}
else
{
min_radix=min_radix>(a[i]-'a'+10)?min_radix:(a[i]-'a'+10+1);
}
}
max_radix=(equal+1)>min_radix?(equal+1):min_radix+1;//find the max base
//使用二分查找找到满足条件的最小基数
while(min_radix<=max_radix)
{
radix=(min_radix+max_radix)/2;
long long sum=number_to_ten(a,radix);
if(sum<0)
{
max_radix=radix-1;
continue;
}
if(sum>equal)//如果中间值大,把上界设为中间值-1
{
max_radix=radix-1;
}
else if(sum<equal)//如果中间值小,把下界设为中间值+1
{
min_radix=radix+1;
}
else//如果中间值满足条件,将上界设为中间值,因为前面有可能还有比中间值更小的满足条件的
{
max_radix=radix;
if(number_to_ten(a, min_radix)==equal)//只有当下界也满足条件的时候,认为下界已经是最小的满足条件的值了,返回下界
{
return min_radix;
}
}
}
//一旦上下界大小颠倒,证明没有满足的情况,退出循环返回-1;
return -1;
}
主函数
#include
#include
#define MAXN 11
long long number_to_ten(char*,long long);
long long find_radix(char*,long long);
int main()
{
char a[MAXN],b[MAXN];
long long tag,radix;
scanf("%s %s %lld %lld",&a,&b,&tag,&radix);
long long res;
if(tag==1)
{
res=find_radix(b, number_to_ten(a,radix));
}
else
{
res=find_radix(a, number_to_ten(b, radix));
}
if(res==-1)
{
printf("Impossible\n");
}
else
{
printf("%lld\n",res);
}
return 0;
}
git仓库:Radix