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
解答:人呐,往往会被自己的认知给局限住。在做这个题时,我原以为radix在[2,36]的范围间,敲破脑壳只能得一半分。后来了解到该题的radix并不局限于此,甚至111(举例)都可以,于是想通。在对radix的范围进行查找时,我先使用了顺序查找,有一个测试用例超时,后来使用二分查找法 ,终于AC!
AC代码如下:
#include<string>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int getDigit(const char c)
{
if(isdigit(c)) return (c - '0');
else return (c - 'a' + 10);
}
long long getDecimalNum(string s2,const int radix)
{
long long n = 0;
reverse(s2.begin(), s2.end());
for(int i = 0; i < s2.size(); ++i)
{
n += getDigit(s2[i]) * pow(radix, i); //相信库函数!
}
return n;
}
int getMiniRadix(const string& s)
{
int mini = getDigit(s[0]);
for(int i = 1; i < s.size(); ++i){
int tmp = getDigit(s[i]);
mini = mini < tmp ? tmp : mini;
}
return (mini+1);
}
int main()
{
string s1, s2;
int tag, radix;
long long n1, n2;
cin >> s1 >> s2 >> tag >> radix;
long long low, middle, high;
if(tag == 2)
{
swap(s1, s2);
}
n1 = getDecimalNum(s1, radix);
low = getMiniRadix(s2);
high = max(low, n1);
//用顺序查找
/*
bool flag = false;
long long i;
for(i = low; i <= high; ++i)
{
long long val = getDecimalNum(s2, i);
if(val == n1){ flag = true; break;}
if(val < 0){ flag = false; break;}
}
if(flag == false) printf("Impossible\n");
else printf("%ld\n", i);
*/
/*使用二分查找法*/
while(low <= high)
{
middle = (low + high) / 2;
long long val = getDecimalNum(s2, middle);
if(val < 0 || val > n1) high = middle - 1;
else if(val == n1) break;
else low = middle+1;
}
if(low <= high) printf("%d\n", middle);
else printf("Impossible\n");
}