题目
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
and
, 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
and
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, anda
-z
represent the decimal numbers 10-35. The last numberradix
is the radix ofif
tag
is 1, or ofif
tag
is 2.
输出
For each test case, print in one line the radix of the other number so that the equation
=
is true. If the equation is impossible, print
Impossible
. If the solution is not unique, output the smallest possible radix.
样例输入
样例输入1:
6 110 1 10
样例输入2:
1 ab 1 2
样例输出
样例输出1:
2
样例输出2:
Impossible
题意理解
给你两个数,如果tag标签位置是1,那么后面给的进制就是第一个数的,我们就要找第二个数的什么进制才能转换成第一个数,如果tag是2,那么给的进制是第二个数的,我们要找什么进制才能让第一个数转变成第二个数。
那么其实我们如果tag是2的时候,我们直接交换这两个数,那么我们永远都是在找第二个的什么进制才能和第一个数相等。
而且其中一个测试点的进制非常大,并不是止步于36进制,我们这里采用二分去寻找这个进制数
此题题意比较简单,但是坑和处理的细节特别多,这里我们分别在每个代码块下面讲解具体的逻辑和细节
注意数字都很大,我们都用 long long 来存
每位权重函数
我们将一个字符串数字上面的每一位都换成相应的数字权重
把字符串换成对应进制对应的数
LL check(char s){
if(s>='0'&&s<='9')return s-'0';
else return s-'a'+10;
}
相应进制的函数
我们将一个字符串数字换成相应的数字,每个位置上面乘以相应的权重,最后我们再去判断,这两个比较的数字是否相同
把字符串换成对应进制对应的数
LL turn(string ss,LL radix){
LL res = 0;
for(int i = 0;i < ss.length();i++) {
res = res*radix + check(ss[i]);
}
return res;
}
找二分的下界
我们要找到我们需要开始二分的最小的进制,那么我们可以观察到
其实在这个字符串中最大的数位加一 就是这个字符串数字的进制
其实就是遍历一遍字符串 找到最大的数位加一 那么这个字符串进制一定不超过这个数
比如 1001 遍历一遍最大的是1 那么这个字符串最大上界是2进制表示的
比如 1239 遍历一遍最大的是9 那么这个字符串最大上界是10进制表示的
LL find_min(string ss){
LL t=0;
for(int i=0;i<ss.size();i++){
t=max(t,check(ss[i]));
}
return max((LL)2,t+1LL);
}
二分
我们找到了目标,找到左边界,右边界就是最大的num,就是我们将这个字符串换成的数字,进制一定不可能超过这个数字。还要注意的是有可能进制太大,我们转换回来的有可能是一个负数,那么我们此时也是认为我们找的这个进制太大了,也是同样缩小我们的右边界
LL num=turn(a,radix);
LL l=find_min(b);
LL r=max(l,num);
while(l<=r){
LL mid=(l+r)>>1;
LL tmp=turn(b,mid);
if(tmp==num){
printf("%lld\n",mid);
return 0;
}
if(tmp<0||tmp>num){
r=mid-1;
}
else l=mid+1;
}
完整代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL ;
typedef pair<int,int> PII;
#define fx first
#define fy second
const int INF =0x3f3f3f3f;
const double II=0x7f7f7f7f;
const int N=1e4+10,M=2e6+10;
const int MOD=1e5+3;
LL check(char s){
if(s>='0'&&s<='9')return s-'0';
else return s-'a'+10;
}
LL turn(string ss,LL radix){
LL res = 0;
for(int i = 0;i < ss.length();i++) {
res = res*radix + check(ss[i]);
}
return res;
}
LL find_min(string ss){
LL t=0;
for(int i=0;i<ss.size();i++){
t=max(t,check(ss[i]));
}
return max((LL)2,t+1LL);
}
int main(){
string a,b;
LL tag,radix;
cin>>a>>b>>tag>>radix;
if(tag==2){
swap(a,b);
}
LL num=turn(a,radix);
LL l=find_min(b);
LL r=max(l,num);
while(l<=r){
LL mid=(l+r)>>1;
LL tmp=turn(b,mid);
if(tmp==num){
printf("%lld\n",mid);
return 0;
}
if(tmp<0||tmp>num){
r=mid-1;
}
else l=mid+1;
}
printf("Impossible\n");
return 0;
}