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.
Input Specification:
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.
Output Specification:
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.
Sample Input 1:
6 110 1 10
Sample Output 1:
2
Sample Input 2:
1 ab 1 2
Sample Output 2:
Impossible
题目大意:
给你两个不超过 10 位的进制数(一个数的进制基数已知,一个未知),让你判断两个数是否相等。
解题思路:
因为一个数的基数已知,所以我们可以将它化为我们熟悉的十进制数。那么现在的问题是我们不知道另外一个数的基数,最容易想到的方法就是暴力枚举了。
因为暴力时间花费过大,所以我们可以换个思路———二分法。
易知未知基数的数的最小基数应该的它所有位的最大数 +1 。如果两个数相等,那么它的最大基数不会超过已知数 +1 。由此可以确定二分的上下界。
注意,我们应该取能够成立的最小基数。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int tag,radix;
char N1[100],N2[100];
int b[110];
int main()
{
scanf("%s%s%d%d",N1,N2,&tag,&radix);
ll len1=strlen(N1),len2=strlen(N2);
ll ans=0,l;
if(tag==1)
{
ll tmp=1;
l=len2;
for(int i=len1-1;i>=0;i--)//化为十进制
{
if(N1[i]>='0'&&N1[i]<='9')
ans+=tmp*(N1[i]-'0');
else
ans+=tmp*(N1[i]-'a'+10);
tmp*=radix;
}
for(int i=len2-1;i>=0;i--)
{
if(N2[i]>='0'&&N2[i]<='9')
b[i]=N2[i]-'0';
else
b[i]=N2[i]-'a'+10;
}
}
else
{
ll tmp=1;
l=len1;
for(int i=len2-1;i>=0;i--)//化为十进制
{
if(N2[i]>='0'&&N2[i]<='9')
ans+=tmp*(N2[i]-'0');
else
ans+=tmp*(N2[i]-'a'+10);
tmp*=radix;
}
for(int i=len1-1;i>=0;i--)
{
if(N1[i]>='0'&&N1[i]<='9')
b[i]=N1[i]-'0';
else
b[i]=N1[i]-'a'+10;
}
}
ll le=0,ri=ans+1;
for(int i=0;i<l;i++)//找最小进制
{
if(b[i]>le)
le=b[i];
}
le++;
ll minn=1e10+1;
int flag=0;
while(le<=ri)//二分找符合的进制
{
ll mid=(le+ri)/2;
ll cnt=0,k=1;
for(int i=l-1;i>=0;i--)
{
cnt+=k*b[i];
k*=mid;
}
if(cnt==ans)
{
if(mid<minn)
minn=mid;
ri=mid-1;
flag=1;
}
else if(cnt>ans||cnt<0)//再mid进制下得到的十进制数cnt比ans大(溢出ll后为负)
ri=mid-1;
else if(cnt<ans)
le=mid+1;
}
if(!flag)
printf("Impossible\n");
else
printf("%lld\n",minn);
return 0;
}