1010 Radix (25 分)
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
这题陷阱很多- -,首先想到的是把已给出进制的那个数转化为10进制,然后另外一个未知进制的数去一个个试可能的进制,然后也转换为10进制和那个已知的比较,看看是否存在一个进制使他们相等,提醒,进制会非常非常大,要用long long存。首先是进制的范围(举个例子):
比如6 110 1 10
这里6已经是10进制了,我们看110,最小的进制是2,那么最大的进制不能超过6+1=7,因为如果进制为8,那么110转换成十进制为9必定比6大,已经无意义了。
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
char n1[15], n2[15];
int t, r;
long long toDecimal(char s[],long long r) {
long long res = 0;
long long temp = 0;
int len = strlen(s);
for (int i = 0; i < len; i++) {
if (s[i]>='0'&&s[i]<='9') {
temp = s[i] - '0';
}
else if (s[i] >= 'a'&&s[i] <= 'z') {
temp = s[i] - 'a' + 10;
}
res = res * r + temp;
}
return res;
}
long long binary(long long l, long long r,long long target) {
while (l <= r) {
long long mid = (l + r) / 2;
if (toDecimal(n2, mid) == target) {
return mid;
}
else if (toDecimal(n2, mid) < 0 || toDecimal(n2, mid) > target) {
r = mid - 1;
}
else if (toDecimal(n2, mid) < target) {
l = mid + 1;
}
}
return -1;
}
long long getMin() {
int min = 0,tmp = 0;
for (int i = 0; i < strlen(n2);i++) {
if (n2[i] >= 'a'&&n2[i] <= 'z') {
tmp = n2[i] - 'a' + 10;
}
else if('0' <= n2[i] && n2[i] <= '9'){
tmp = n2[i] - '0';
}
if (tmp > min) min = tmp + 1;
}
if (min < 2) return 2;
return min;
}
int main() {
long long res = 0, radix = 0;
scanf("%s %s %d %d", n1, n2, &t, &r);
if (t == 2) swap(n1, n2);
res = toDecimal(n1, r);
long long left = getMin();//比如2进制只有0和1,那么最低进制就是该字符串最大数字+1
long long right = max(left, res) + 1;//最大进制不能超过res+1,因为超过了肯定比res大
radix = binary(left, right, res);
if (radix != -1) printf("%lld\n", radix);
else printf("Impossible");
return 0;
}