【笨方法學PAT】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
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
二、題目大意
給定n1、n2兩個數,求可以是兩者相等的進位制;如果沒有,輸出Impossible
三、考點
二分法、取值範圍
PS. 這道題目比較坑,沒有對取值範圍說明,int 肯定會越界,long long int 可能也會;最大取值範圍也沒有說明
四、解題思路
1、如果 tag == 2 ,交換,之後遇到類似的題目,也可以這樣處理;
2、求 n1 的10進位制數值,按照二分法求解 n2 對應 radix 下的數值,判斷是否相等,相等的話,退出,不相等的話,更新 left 和right 的值;
3、在二分法求解的過程中,long long int 可能會越界,如果求得的值 < 0 說明越界,radix 過大。這也是測試系統的一個問題,有可能全都越界,這種情況很難處理。
五、程式碼
#include<iostream>
#include<algorithm>
#include<string>
#include<math.h>
using namespace std;
long long int to10(string s, int radix) {
long long int sum = 0;
for (int i = 0; i < s.length(); ++i) {
if (isdigit(s[i]))
sum = sum*radix+s[i] - '0';
else if (isalpha(s[i]))
sum = sum*radix+s[i] - 'a'+10;
}
return sum;
}
long long int findRadix(long long int n, string s, long long int left, long long int right) {
long long int m;
while (left <= right) {
long long int mid = (left + right) / 2;
m = to10(s, mid);
if (m == n) {
return mid;
}
//進位制太大
else if (m > n||m<0)
right = mid-1;
//進位制太小
else
left = mid+1;
}
return -1;
}
int main() {
string s1, s2;
//讀取資料,預處理
int tag, radix;
cin >> s1 >> s2 >> tag >> radix;
if (tag == 2)
swap(s1, s2);
//s1轉10進位制
long long int n1, n2;
n1 = to10(s1, radix);
//尋找s2的最小進位制
long long int min_radix = 0;
for (int i = 0; i < s2.length(); ++i) {
if (isdigit(s2[i])) {
if (s2[i] - '0' > min_radix)
min_radix = s2[i] - '0'+1;
}
else if (isalpha(s2[i])) {
if (s2[i] - 'a' + 10 > min_radix)
min_radix = s2[i] - 'a' + 10+1;
}
}
//二分法
long long int max_radix = max(n1, min_radix);
long long int ans = findRadix(n1, s2, min_radix, max_radix);
//輸出結果
if (ans == -1)
cout << "Impossible";
else
cout << ans;
system("pause");
return 0;
}