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
思路
- 二分:对一个确定的数字串来说,它的进制越大,该数字串转换为十进制的结果也就越大。
注意点
- 使用遍历进制的暴力法会超时,因使用二分法。
- 本题的变量尽量使用 long long 类型。另外,经测试得到,本题中 radix 的范围最大为 INT_MAX ,即2^{31}-1,因此必须在在计算过程中判断是否溢出。
- N2 进制的下界为所有数位中最大的那个+1,上界为 N1 的十进制(num1)与下界(lower)的较大值+1(即 max(num1, lower) + 1)。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char n1[11], n2[11], temp[11];
int tag;
long long radix, num1, inf = (1LL << 63) - 1;
long long strToNum(char str[], long long radix, long long upper) {
int len = strlen(str);
long long num = 0;
for (int i = 0; i < len; i++) {
long long digit;
if (str[i] >= 'a' && str[i] <= 'z') {
digit = str[i] - 'a' + 10;
} else {
digit = str[i] - '0';
}
num = num * radix + digit;
if (num < 0 || num > upper) {
return -1;
}
}
return num;
}
long long findLower(char str[]) {
long long maxDigit = -1;
int len = strlen(str);
for (int i = 0; i < len; i++) {
long long digit;
if (str[i] >= 'a' && str[i] <= 'z') {
digit = str[i] - 'a' + 10;
} else {
digit = str[i] - '0';
}
if (digit > maxDigit) {
maxDigit = digit;
}
}
return maxDigit + 1;
}
int binarySearch(long long left, long long right, char str[], long long upper) {
long long mid, num2;
while (left <= right) {
mid = left + (right - left) / 2;
long long num2 = strToNum(n2, mid, upper);
if (num2 == num1) {
return mid;
} else if (num2 > num1 || num2 == -1) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
int main() {
scanf("%s %s %d %d", n1, n2, &tag, &radix);
if (tag == 2) {
strcpy(temp, n1);
strcpy(n1, n2);
strcpy(n2, temp);
}
long long lower = findLower(n2);
num1 = strToNum(n1, radix, inf);
long long radix2 = binarySearch(lower, max(num1, lower) + 1, n2, num1);
if (radix2 == -1) {
printf("Impossible");
} else {
printf("%d", radix2);
}
return 0;
}