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
这道题如果常规来做会有两个测试点超时,所以ac一定要用二分法。只需注意判断溢出即可,因为基数取上限时即使是ll也会溢出。额外需要注意的点是high取max(low,sum1);因为考虑到6,6,1,10。的情况,low为7,sum1位6,如果无脑取sum1则下界大于上界,况且6的最小进制本就该是7。
AC代码:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
string s1, s2;
long long tg, r;
cin>>s1>>s2>>tg>>r;
if (tg == 2) { //保证s1始终对应给出的radix,s2为待求
string s;
s = s1;
s1 = s2;
s2 = s;
}
int len1 = s1.length();
int len2 = s2.length();
long long sum1 = 0, sum2 = 0;
for (int i = 0; i < len1; i++) { //求出十进制下s1的值
sum1 = sum1 * r;
if (s1[i] <= '9' && s1[i] >= '0') {
sum1 += s1[i] - '0';
} else sum1 += s1[i] - 'a' + 10;
}
int r_max = 0;
for (int i = 0; i < len2; i++) { //定下界
if (s2[i] <= '9' && s2[i] >= '0')
r_max = max(r_max, s2[i]-'0');
else
r_max = max(r_max, s2[i] - 'a' + 10);
}
long long low = r_max + 1;
long long high = max(low, sum1);
long long mid;
while (low <= high) { //二分法
mid = (low + high) / 2;
sum2 = 0; //不要忘了重置0哦
for (int i = 0; i < len2; i++) {
sum2 = sum2 * mid;
if (s2[i] <= '9' && s2[i] >= '0')
sum2 += s2[i] - '0';
else
sum2 += s2[i] - 'a' + 10;
}
if (sum2 > sum1 || sum2 < 0) //一定要先判断是否为负,溢出说明mid过大应当high向左移动
high = mid - 1;
else if (sum2 < sum1) //若把这个当做第一个条件,则溢出时会low向右移动,导致不断溢出,不断循环
low = mid + 1;
else {
cout<<mid;
return 0;
}
}
cout<<"Impossible";
return 0;
}