1. 程式人生 > >PAT甲級真題(二分)——1010 Radix (25 分)

PAT甲級真題(二分)——1010 Radix (25 分)

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 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

題目大意:

給定兩串數字,已知其中一個的基數,求另一串數使兩數相等的基數,如果不存在這樣的基數,輸出Impossible。

題目解析:

用long long型變數儲存轉換後的數N,然後用二分法求另一個的基數。
要注意的是:

  • low取這串數字的最大數加一,high取max(low,N);
  • 由於在計算進位制轉換後的數字temp時可能會發生溢位,所以當temp<0時應縮小上界;

具體程式碼:

#include<iostream>
#include<algorithm>
#include<cctype>
using namespace std;

long long convert(string s,long long radix){
	long long sum=0;
	int temp;
	for(int i=0;i<s.size();i++){
		temp=isdigit(s[i])?s[i]-'0':s[i]-'a'+10;
		sum=sum*radix+temp;
	}
	return sum;
}

int main() {
	string n[3];
	long long tag,radix,num=0;
	cin>>n[1]>>n[2]>>tag>>radix;
	num=convert(n[tag],radix);
	tag=(tag==1)?2:1;
	//利用二分法找出滿足的基數
	char it=*max_element(n[tag].begin(), n[tag].end());
	long long low=(isdigit(it)?it-'0':it-'a'+10)+1;
	long long high=num>low?num:low,mid;
	while(low<=high){
		mid=low+(high-low)/2;
		long long temp=convert(n[tag],mid);
		if(temp==num){
			cout<<mid;
			return 0;
		}else if(temp<0||temp>num)//如果大於num,則說明基數太大了;如果溢位了temp就小於0 
			high=mid-1;
		else
			low=mid+1; 
	}
	cout<<"Impossible";
	return 0;
}