PAT 甲級 A1010

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 N​1and N​2​​ , 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 N2each 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

總結

  1. 使用二分法不會超時,但二分的上下界得確定。二分的下界low爲未知進制的所有數位中的最大數加1,上界爲max(low,N1)+1。二分的下界如果簡單確定爲2,會有兩個測試點過不去。如果定爲0,會有更多點過不去,佛了。
  2. 進制轉化時,long long類型的數照樣會發生上溢,因此也要把這種情況加入二分的判斷中
  3. 輸出的進制需要是儘可能小的進制,因此每次求到一個解都需要比較
  4. 還有一點值得提,當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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章