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
思路:
具体求进制不难,直接用字符串输入,根据0-9、a-z来分别判断,分类之后就可以根据两个数字的十进制值来判断
坑点:
- 代码中并没有说,radix的取值范围,所以radix的范围是[2,+无穷),结合题目意思之后,其实radix范围时[1,N1+1]
- 有了radix后的结果甚至会超过long long的范围,当其超过后,结果<0,就要在其左区间中查找
特殊测试点:
输入:0 0 1 100
输出:1
注意:
- 题目中没说明具体数的取值范围时,就要想到可能会是无穷,然后再确定范围
- 对进制的理解,进制>=本数中单个最大数值+1
代码:(C++)
#include<iostream>
#include<cmath>
using namespace std;
long long changeToD(string str, long long radix) //转变为十进制
{
long long re = 0;
for(int i=0; i<str.length(); i++)
{
if(str[i] >= '0' && str[i] <= '9')
re += (str[i] - '0') * pow(radix, str.length()-i-1);
else if(str[i] >= 'a' && str[i] <= 'z')
re += (str[i] - 'a' + 10) * pow(radix, str.length()-i-1);
}
return re;
}
int getMinRadix(string str) //获取最小进制
{
int max_n = 0;
for(int i=0; i<str.length(); i++)
{
if(str[i] >= '0' && str[i] <= '9')
max_n = max(max_n,str[i] - '0');
else if(str[i] >= 'a' && str[i] <= 'z')
max_n = max(max_n,str[i] - 'a' + 10);
}
return max_n+1;
}
int main()
{
string N1,N2;
int tag;
long long radix;
cin>>N1>>N2>>tag>>radix;
long long re1=0, re2; //保存题目提供的那数的十进制,用long long保存
if(tag == 2) //如果为tag为2,交换位置即可,后面代码不用变
N1.swap(N2);
re1 = changeToD(N1, radix);
long long left = getMinRadix(N2);
long long right = re1 + 1; //最大进制可能为re1+1
long long i, mid = re1;
while(left <= right) //二分法判断
{
i = (left + right)/2;
re2 = changeToD(N2, i);
if(re1 == re2)
{
cout<<i;
return 0;
}
else if(re2 > re1 || re2 <0) //当re2<0时,说明其越界了,下一次得在i的左边找
right = i - 1;
else
left = i + 1;
}
cout<<"Impossible";
return 0;
}