[PTA] PAT(A) 1010 Radix (25 分)
Problem
portal: 1010 Radix
Description
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 \(N_{1}\) and \(N_{2}\) , your task is to find the radix of one number while that of the other is given.
## InputEach 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.
## OutputFor 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 ### Sample Input1 ``` 6 110 1 10 ``` ### Sample Output1 ``` 2 ``` ### Sample Input2 ``` 1 ab 1 2 ``` ### Sample Output2 ``` Impossible ``` # Solution ## Analysis 首先,计算出题目所给出的tag对应的数所对应的真值(也就是十进制值),然后通过这个真值和另一个题目给出的数,通过get_result()函数,找出满足两个数真值相等的进制,如果不存在,将返回0; 自己做的时候想的很简单,以为进制的范围就只是2~36,然后就错了好多,最后还是参考别人的文章,完善了get_result()函数。 在get_result()函数中,先找到满足参数的最小进制,然后进行尝试,如果可以的话,直接输出结果,如果不行的话,再考虑二分查找。二分查找的范围是$[满足参数的最小进制,真值+1)$,我使用二分一般是将right作为永远不会查到的边界使用,所以这里是真值+1。 代码里没有注释,但是函数名也算是比较能看。 ## Code ```cpp #includeint get_value_of_char(char ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
} else {
return ch - 'a' + 10;
}
}
long long get_true_value(string N, int r) {
long long value = 0;
for (int i = 0; i < N.size(); i++) {
value = value * r + get_value_of_char(N[i]);
}
return value;
}
int get_min_radix(string N) {
int max_value = 0;
for (int i = 0; i < N.size(); i++) {
max_value = max(max_value, get_value_of_char(N[i]));
}
return max_value + 1;
}
long long get_result(string N, long long true_value) {
long long radix = get_min_radix(N);
if (true_value == get_true_value(N, radix)) {
return radix;
}
long long left = radix, right = true_value + 1, mid;
while (left < right) {
mid = (left + right) / 2;
long long value = get_true_value(N, mid);
if (value == true_value) {
return mid;
} else if (value < 0 || value > true_value) {
right = mid;
} else {
left = mid + 1;
}
}
return 0;
}
int main(void) {
string N1, N2;
long long tag, radix, result;
long long true_value;
cin >> N1 >> N2 >> tag >> radix;
if (tag == 1) {
true_value = get_true_value(N1, radix);
result = get_result(N2, true_value);
} else {
true_value = get_true_value(N2, radix);
result = get_result(N1, true_value);
}
if (result == 0) {
cout << "Impossible\n";
} else {
cout << result << endl;
}
}
## Reference
[柳婼 の blog](https://www.liuchuo.net/archives/2458) 提供了当计算出现溢出时的特殊判定思路
[Loull](https://www.cnblogs.com/549294286/p/3571604.html) 提供了二分上下界确定时我的那种方法出现的不足的弥补(忘记+1)