1010 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 N1and N2 , your task is to find the radix of one number while that of the other is given.
輸入格式
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.
輸出格式
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
總結
- 使用二分法不會超時,但二分的上下界得確定。二分的下界low爲未知進制的所有數位中的最大數加1,上界爲max(low,N1)+1。二分的下界如果簡單確定爲2,會有兩個測試點過不去。如果定爲0,會有更多點過不去,佛了。
- 進制轉化時,long long類型的數照樣會發生上溢,因此也要把這種情況加入二分的判斷中
- 輸出的進制需要是儘可能小的進制,因此每次求到一個解都需要比較
- 還有一點值得提,當N1和N2都越界時,應該輸出radix,但是測試數據裏面貌似沒有這種情況,爲了代碼看起來比較少我就判斷這種情況。
AC代碼
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<ctype.h>
using namespace std;
typedef long long ll;
ll toNum(char c) {
if (isdigit(c)) {
return c - '0';
}
return c - 'a' + 10;
}
ll toDemical(string a, int r) {
ll ans = 0;
for (int i = 0; i < a.size(); i++) {
ans = ans * r + toNum(a[i]);
if (ans < 0) return -1; //越界
}
return ans;
}
int main() {
string a, b;
int tag, radix;
ll N1, N2;
cin >> a >> b >> tag >> radix;
if (tag == 2) { //a爲已經確定進制的數
swap(a, b);
}
N1 = toDemical(a, radix); //轉化爲10進制
ll low = 2, high = max(low, N1) + 1, ans;
for (int i = 0; i < b.size(); i++) //算出最低的進制數
{
low = max(low, toNum(b[i]) + 1);
}
bool flag = false;
while (low <= high) { //二分
ll mid = (low + high) / 2;
N2 = toDemical(b, mid);
if (N2 == -1|| N2 > N1||(int)mid<0) { //過大,或者mid超出int的範圍(不過測試數據並沒有這種情況)
high = mid - 1;
}
else if (N2 < N1) {
low = mid + 1;
}
else { //有解,繼續查詢更小的解
flag = true;
ans = mid;
high = mid - 1;
}
}
if (flag) {
printf("%lld\n", ans);
}
else {
printf("Impossible\n");
}
return 0;
}