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
题目不难,将已经确定进制的数N1转换为十进制数,对未确定进制的数N2,利用二分查找确定其进制。二分过程中,若N2转为十进制比N1的十进制大,则说明当前进制比较大,应该向左子区间继续二分,否则向右子区间二分。
需要注意的是:二分时进制的下界为N2所有数位中最大值+1,上界应该是N1的十进制数+1(而不是36),所以上下界应该和十进制数一样采用long型存储。二分过程中,对N2转换为十进制时,可能会溢出(记为-1),这时N2一定大于N1,所以进制较大应往左子区间二分。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static int map[] = new int[128];
static void init() {
for (char c = '0'; c <= '9'; c++) {
map[c] = c - '0';
}
for (char c = 'a'; c <= 'z'; c++) {
map[c] = c - 'a' + 10;
}
}
// x转换成十进制,t为上界
static long translate(String x, long radix, long t) {
long res = 0;
for (int i = 0; i < x.length(); i++) {
char c = x.charAt(i);
// 进制转换
res = map[c] + res * radix;
if (res < 0 || res > t)
return -1;// 溢出或超过N1
}
return res;
}
// 找出x中最大数位
static int getLargestNum(String x) {
int ans = -1;
for (int i = 0; i < x.length(); i++) {
if (map[x.charAt(i)] > ans)
ans = map[x.charAt(i)];
}
return ans + 1;
}
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String[] line = reader.readLine().split(" ");
int tag = Integer.valueOf(line[2]), radix = Integer.valueOf(line[3]);
String N1 = line[tag - 1], N2 = line[tag == 1 ? 1 : 0];// N1指向已知进制的数
init();// 映射数位
long t1 = translate(N1, radix, Long.MAX_VALUE);// 将N1从radix转为十进制
long left = getLargestNum(N2);// N2中最大数位+1,即为二分下界
long right = t1 + 1;// 上界:n1+1(不是36)
long ans = -1;
while (left <= right) {
long mid = (left + right) / 2;
long t2 = translate(N2, mid, t1);// 从mid进制转为十进制
if (t2 == t1) {
ans = mid;
break;
} else if (t2 > 0 && t2 < t1) {// 没有溢出,小于t1
left = mid + 1;// 进制太小,向右子区间继续二分
} else {// 大于t1
right = mid - 1;
}
}
if (left > right)
System.out.println("Impossible");
else
System.out.println(ans);
}
}