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:
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.
IDEA
1.使用二分法遍历,上界下界确定。下界为待确定进制数字最大一位数+1(即是能判断的最小进制),上界取max(下界,已确定数的十进制值)
2.数据位数很大可能,用long long类型
3.比较坑一点,没有说清楚最小进制从2进制开始;最大进制可能特别特别大;两个数相同非1,去radix,相同为1取2
CODE
#include <iostream>
#include <cstring>
#include<cmath>
using namespace std;
long long chartoInt (char c){
long long b;
if(c>='0'&&c<='9'){
b=c-'0';
}else if(c>='a'&&c<='z'){
b=c-'a'+10;
}
return b;
}
/*
long long changetoDec(string s,long long radix){
long long a=0,b;
for(long long i=s.length()-1,j=0;i>=0;i--){
b=chartoInt(s[i]);
a+=b*pow(radix,j++);
}
return a;
}
*/
//转换为十进制
long long changetoDec(string s,long long radix)
{
long long m=1,a=0;
for(long long i=s.length()-1;i>=0;i--)
{
long long b=chartoInt(s[i]);
a+=b*m;
m*=radix;
}
return a;
}
//寻找下界,遍历字符型数字,选最大的数+1
long long findLow(string s)
{
long long max=0;
for(long long i=s.length()-1;i>=0;i--)
{
long long b=chartoInt(s[i]);
if(b>max)
max=b;
}
return max+1;
}
long long findHigh(long long low,long long target){
if(low>target){
return low+1;
}else{
return target+1;
}
}
//二分查找时会用到的比较函数,用于剪枝
int comp(string s,long long radix ,long long target)
{
long long m=1,a=0;
for(long long i=s.length()-1;i>=0;i--)
{
long long b=chartoInt(s[i]);
a+=b*m;
m*=radix;
if(a>target)//还没有遍历完,就超出应有大小了,说明不存在
return -1;
}
if(a>target)
return -1;
else if(a<target)
return 0;//遍历完了,仍然a<target,说明radix还小
else
return 1;//找到了
}
//二分法
long long binarySearch(string s,long long low,long long high,long long target)
{
long long mid = low;
long long flag;
while(low<=high)
{
flag= comp(s,mid,target);
if(flag==-1){
high = mid-1;
}
else if(flag==0){
low = mid +1;
}
else{
return mid;
}
mid = (low + high)/2;
}
return -1;
}
int main()
{
string n1,n2;
long long tag;
long long radix;
cin>>n1>>n2>>tag>>radix;
if(n1==n2){//当两个数相等且不为 1 时,输出题中给出的 radix
if(n1!="1"){
cout<<radix;
return 0;
}
if(n1=="1"){//当两个数都是 1 时,输出2
cout<<2;
return 0;
}
}
long long target,low, high,flag;
if(tag==1)
{
target=changetoDec(n1,radix);
low = findLow(n2);
high=findHigh(low,target);
flag = binarySearch(n2,low,high,target);
}
else if(tag==2)
{
target=changetoDec(n2,radix);
low = findLow(n1);
high=findHigh(low,target);
flag = binarySearch(n1,low,high,target);
}
if(flag==-1)
cout<<"Impossible"<<endl;
else
cout<<flag<<endl;
}