1010 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
题意:使两个不同进制的数相等。
Code:
#include<iostream> #include<algorithm> using namespace std; int arr[26] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35}; int Tochange(char c) { int t; if (c > '9') { t = arr[c-'a']; } else { t = c - '0'; } return t; } int StrToNum(string s, int n) { int ret = 0; int b, e = 1; reverse(s.begin(), s.end()); for (int i = 0; i < s.length(); ++i) { b = Tochange(s[i]); if (b >= n) return -1; ret += b * e; e *= n; } return ret; } int main() { string N1, N2; int tag, t; int redix; cin >> N1 >> N2 >> tag >> redix; t = redix; int num1, num2; if (tag == 1) { num1 = StrToNum(N1, t); for (int i = 2; i <= 35; ++i) { num2 = StrToNum(N2, i); if (num1 == num2) { cout << i; return 0; } } } else { num2 = StrToNum(N2, t); for (int i = 2; i <= 35; ++i) { num1 = StrToNum(N1, i); if (num1 == num2) { cout << i; return 0; } } } cout << "Impossible"; return 0; }
这个代码通过了部分测试数据,有些数据返回的结果是Wrong Answer。
看了一下别人的代码,发现上面出错的原因在于,在寻找基数的时候寻找的范围并不是在2~36之间,而是在2~+∞。如果还是用原来的遍历查找的话肯定是不行的,所以想到用二分法来查找。在用二分法来查找的时候要注意
while (low <= high) { }
while循环中是<=而不是<。
还有就是35的10次方是一个很大的数字,开数据类型的时候要开成long long类型的。其实开成long long类型的之后还是会溢出,成为负数,所以在检测的时候会有这一句代码
else if (temp < 0 || temp > n) high = mid - 1;
Code:
#include<iostream> #include<algorithm> #include<cmath> #include<cctype> using namespace std; int arr[26] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35}; int Tochange(char c) { int t; if (c > '9') { t = arr[c-'a']; } else { t = c - '0'; } return t; } long long StrToNum(string s, long long n) { int b; long long ret = 0; long long e = 1; reverse(s.begin(), s.end()); for (int i = 0; i < s.length(); ++i) { b = Tochange(s[i]); ret += b * e; e *= n; } return ret; } void findRedix(string s, long long n) { long long temp; char c = *max_element(s.begin(), s.end()); long long low = Tochange(c) + 1; long long high = max(low, n); while (low <= high) { long long mid = (low + high) / 2; temp = StrToNum(s, mid); if (temp == n) { cout << mid; return ; } else if (temp < 0 || temp > n) high = mid - 1; else low = mid + 1; } cout << "Impossible"; } int main() { string N1, N2; int tag, redix; cin >> N1 >> N2 >> tag >> redix; long long num1, num2; if (tag == 1) { num1 = StrToNum(N1, redix); findRedix(N2, num1); } else { num2 = StrToNum(N2, redix); findRedix(N1, num2); } return 0; }