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
解题思路:
按照要求,将N1或者N2先转换成十进制数,然后再求出进制转换的上下限,通过二分查找来找到最小的那个符合题意的进制使得N1==N2。
进制的下限很明显就是N1或N2字符串里面最大的那一个数字加一(不然的话就不符合进制转换的定义了,例如2进制的数里面最大是1)。进制转换的上限就是先前你转换成十进制的数字加一,打个比方,你将N1转换成10进制后是12345,N2最小是个位数,只能在进制12346时可能满足N1==N2。
易错点:
1. 测试点0是N1,N2相同的时候,需要找到最小的进制使得答案满足。
2.定义的时候应该定义成long long int,因为它的进制可能很大很大,radix也可能很大很大。
3.因为题目里面的答案是包括在long long int里面的,但是当你通过进制转换的过程当中,可能会出现超过规定范围的情况,例如’aaaaa‘ 在12345678进制的时候,转换成十进制就会变成负数。这个时候你需要默认它大于实际值,直接并入大于那一种情况处理就行。
//详细情况可以看代码注释
代码:
#include<bits/stdc++.h>
using namespace std;
string N1,N2;
int tag;
long long int radix,ten_N1,ten_N2;
long long int result=1;
int flag=0;
long long int turn_ten(string a,long long int b){//转换成10进制的数字
long long int sum=0;int k=0;
for(int i=a.size()-1;i>=0;i--){
if(a[i]>='0'&&a[i]<='9')
sum+=(a[i]-'0')*pow(b,k++);
else if(a[i]>='a'&&a[i]<='z')
sum+=(a[i]-'a'+10)*pow(b,k++);
}
return sum;
}
int return_l(string a){//求出下界,就是字符串内最大的数+1
int b=0;
for(int i=0;i<a.size();i++){
int temp=0;
if(a[i]>='a'&&a[i]<='z') temp=a[i]-'a'+10;
else temp=a[i]-'0';
if(temp>b) b=temp;
}
return b;
}
int main(){
cin>>N1>>N2>>tag>>radix;
if(tag==1){//tag==1时的处理
ten_N1 = turn_ten(N1,radix);
long long int r = ten_N1+1;
int l = return_l(N2)+1;
while(l<=r){
long long int mid=(l+r)/2;
if(turn_ten(N2,mid)==ten_N1){//当他们相等的时候就把值赋值给result
result=mid;
r=mid-1;//需要找到最小的,所以r还需要往左移动继续找
flag=1;
}
else if(turn_ten(N2,mid)>ten_N1||turn_ten(N2,mid)<0){
//当大于,或者答案小于0时,右界往左移动
r=mid-1;
}
else if(turn_ten(N2,mid)<ten_N1){
//当小于时,左界往右移动
l=mid+1;
}
}
}
else if(tag==2){//tag==2时的处理,与1相似
ten_N2 = turn_ten(N2,radix);
long long int r = ten_N2+1;
int l = return_l(N1)+1;
while(l<=r){
long long int mid=(l+r)/2;
if(turn_ten(N1,mid)==ten_N2){
result=mid;
r=mid-1;
flag=1;
}
else if(turn_ten(N1,mid)>ten_N2||turn_ten(N1,mid)<0){
r=mid-1;
}
else if(turn_ten(N1,mid)<ten_N2){
l=mid+1;
}
}
}
if(flag) cout<<result;
else cout<<"Impossible";
return 0;
}