Radix
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
注意:
- 使用二分查找的方法,因为当输入的进制过大时,例如输入:99999999 1 1 99999999时,如果从小到大开始查找就会花费很多时间,可以采用二分查找法,确定查找的上界和下界。
- 二分查找时,查找的下界很好确定,就是要确定进制的数字的最小进制,例如当要确定的数字为123时,则他的最小进制为4,输入的数字为abc时,最小进制为13,以此类推;查找的上界可以直接确定为已知进制的十进制大小。
- 当输入的数字或者进制过大时,可能会出现越界的现象,可以直接使用Java中的BigInteger类(但是我使用这个的时候出现了内存超限的提示还没有深究);然后可以使用long,但是要判断是否越界即在计算的过程中有没有出现小于0的情况;
- 在确定了上界和下界之后,二分查找之前,要将上界调整为上界和下界的最大值。如当输入为:1 1 1 10,按照一般方法确定的下界为2,上界为1,此时如果直接进行二分查找,会直接返回-1,所以此时要将上界确定为较大的2。
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Radix {
static long standard;
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String[] str = bufferedReader.readLine().split(" ");
long standardRadix = Long.parseLong(str[3]);
String toJudge;
if (Integer.parseInt(str[2]) == 1) {
standard = convertToRadix(str[0], standardRadix);
toJudge = str[1];
} else {
standard = convertToRadix(str[1], standardRadix);
toJudge = str[0];
}
long min = findMin(toJudge) + 1;
long result = findResult(toJudge, min, standard);
if (result == -1) System.out.print("Impossible");
else System.out.print(result);
}
/**
* 通过二分法找到对应的进制
*
* @return 找到则返回对应的数制,否则返回-1
*/
private static long findResult(String toJudge, long left, long right) {
long mid;
right = Math.max(left, right);
while (left <= right) {
mid = (left + right) / 2;
long temp = convertToRadix(toJudge, mid);
if (temp == standard)
return mid;
else if (temp < 0 || temp > standard)
right = mid - 1;
else left = mid + 1;
}
return -1;
}
/**
* 将每位数转换为对应的数字
*
* @param c 该位的字符
* @return 代表的数字的大小
*/
private static int convertToDigit(char c) {
if (c < 58) return c - 48;
else return c - 87;
}
/**
* 找到二分的左边界
* 即根据每位数的大小找到最小的进制,例如123,最小进制为4进制
*
* @param str 字符串表示的进制数
* @return 最小进制
*/
private static int findMin(String str) {
int result = 0;
for (int i = 0; i < str.length(); i++) {
result = Math.max(result, convertToDigit(str.charAt(i)));
}
return result;
}
/**
* 按照数制转换为对应的十进制数
*
* @param str 要转换的字符串
* @param radix 数制
* @return 转换后的十进制数的大小
*/
private static long convertToRadix(String str, long radix) {
long tempRadix = 1;
long result = 0;
for (int i = str.length() - 1; i >= 0; i--) {
result += tempRadix * convertToDigit(str.charAt(i));
tempRadix *= radix;
}
return result;
}
}