参考博客:https://blog.csdn.net/Joyceyang_999/article/details/81908299
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,tag,radix.N1,N2是不超过十位的数,可以有数字和小写字母组成。tag是1 时,N1是radix 进制的数,tag 是2 时N2 是radix 进制的数。然后找另一个数在什么进制下两个数相等,如果有就输出这个进制,如果没有就输出 Impossible
思路:
这里就是先将已知进制的数转化成10进制的数,然后再去找另一个数的进制。
开始我是直接暴力枚举,得了23分,可是后边几个怎么也过不了,看了题解才知道要用到二分找。
注意:
1.进制的区间范围 N2的下限通过找到其中最大的字符对应的数字Max加1即可。而N2的上限不能直接等于N1+1,因为若N1等于0,那么上限值就为1,最小的进制为2进制。所以要先判断Max是否大于N1的十进制值,若大于,则上限Max+1,反之则N1的十进制+1
2. 输入的N1/N2转化成十进制后可能超过Int的范围,要用long long 由于是用他们转化成十进制后的数作为上限,因此进制的上限值以及进制的中间值都可能会超过Int的范围,所以都要用long long
3. 转化时可能存在溢出情况 由于进制的上限会非常大,在转化时就有可能会溢出,溢出后结果<0,所以若转化成十进制后<0,上限要缩小
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<cmath>
const int maxn=1e5+5;
typedef long long ll;
using namespace std;
long long findMax(string s){//找最大的一位
long long Max=0;
for(int i=0;i<s.length();i++){
if(s[i]>='0'&&s[i]<='9'){
Max=max(Max,(long long)(s[i]-'0'));
}else{
Max=max(Max,(long long)(s[i]-'a'+10));
}
}
return Max;
}
long long trans(string s,long long radix){//radix进制转十进制
long long sum=0;
for(int i=0;i<s.length() ;i++){
if(s[i]>='0'&&s[i]<='9'){
sum=sum*radix+s[i]-'0';
}else{
sum=sum*radix+(s[i]-'a'+10);
}
}
return sum;
}
void find(string num1,string num2,int radix){//已知num1
long long number;
number=trans(num1,radix);
long long l=findMax(num2)+1;
long long r=max(number,l)+1;
while(l<=r){
long long mid=(l+r)/2;
long long temp=trans(num2,mid);
if(temp==number){
cout<<mid;
break;
}else if(temp>number||temp<0){
r=mid-1;
}else{
l=mid+1;
}
}
if(l>r){
cout<<"Impossible";
}
}
int main(){
string num1,num2;
int tag,radix;
cin>>num1>>num2>>tag>>radix;
if(tag==1){
find(num1,num2,radix);
}else{
find(num2,num1,radix);
}
return 0;
}