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
#include <stdio.h> #include <stdlib.h> #include <string> #include <iostream> #include <math.h> #include <algorithm> using namespace std; long long str2num(string s, long long radix){ long long num = 0; for (int i = 0; i < s.length(); i++){ if (s[i] >= '0' && s[i] <= '9')num = num + (s[i] - '0')*pow(radix, s.length() - i - 1); else if (s[i] >= 'a' && s[i] <= 'z')num = num + (s[i] - 'a' + 10)*pow(radix, s.length() - i - 1); } return num; } long long min_radix(string s){ long long max_r = 0; for (int i = 0; i < s.length(); i++){ long long tmp; if (s[i] >= '0' && s[i] <= '9')tmp = s[i] - '0'; else if (s[i] >= 'a' && s[i] <= 'z')tmp = s[i] - 'a' + 10; if (tmp>max_r)max_r = tmp; } return max_r+1; } int main(){ string n1, n2; long long num1 = 0, num2 = 0; long long tag, radix; long long min_r = 0, res = 0, le, ri, mid; cin >> n1 >> n2 >> tag >> radix; if (tag == 1){ num1 = str2num(n1, radix); min_r = min_radix(n2); } else{ num1 = str2num(n2, radix); min_r = min_radix(n1); } le = min_r; ri = max(le,num1); while (le <= ri){ mid = (le + ri) / 2; num2 = str2num(tag==1?n2:n1, mid); if (num2<0 || num2 > num1)ri = mid - 1; else if (num2 < num1)le = mid + 1; else{ res = mid; break; } } if (res != 0)printf("%d", res); else printf("Impossible"); system("pause"); }
注意点:第一:两个输入题目保证不超过10位,但没说几进制,所以可能会很大,不过好在测试数据都没有超过long long。
第二:针对这种两个换一换的情况最好写函数,简洁明了,还可以直接用swap函数(algorithm头文件里)
第三:由于没有明确上界,需要自己判断
第四:范围太大,逐个遍历会超时,要用二分法
第五:由于指定数不超过long long,在特定radix下得到的值溢出long long(小于0),说明太大
第六:基数的下限通过遍历字符串得到,下限肯定比最大的数大1
第七:上界为ri = max(le,num1);,这里一直想不通,其实是这样的,如果已知数比最小基数要小,用最小基数也还是可能算出已知数来的,比如已知10进制的8,未知数为8,9进制就可以了。