PAT 1010. Radix

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

分析

这道题的测试数据比较多,测试点10和7比较难过。首先如果不用二分搜索法,用暴力遍历的话,测试点7超时。如果用二分搜索法却没有考虑到long long int也会溢出的情况,则测试点10错误。

代码如下

#include<iostream>
#include<math.h>
#include<cctype>
#include<algorithm>
using namespace std;
/*将radix进制的数转化为十进制的数*/ 
long long int stonum(string s,long long int radix){ 
	long long int num=0,temp=0;
	for(int i=s.size()-1;i>=0;i--){
		if(isalpha(s[i]))
		num+=(s[i]-87)*pow(radix,temp++);
		else
		num+=(s[i]-'0')*pow(radix,temp++);
	}
	return num;
}
/*二分搜索法*/ 
long long int binsearch(long long int l,long long int r,long long int n1,string s){
	while(l<=r){
		long long int mid=(l+r)/2,sum=0,temp=0;
     	sum=stonum(s,mid);
     	if(sum==n1)
		return mid;
		if(sum<0) r=mid-1; // 这一步则是处理溢出情况,当溢出时,sum<0 
		else 
		sum<n1?l=mid+1:r=mid-1;
	}
	return -1;
}
int main(){
	string s1,s2,s;
	int tag,radix;
	long long int n1=0,n2=0; // 这题的数据可能很大都用long long int 
	cin>>s1>>s2>>tag>>radix;
	s=tag>1?s2:s1; //把s赋上tag所指的数 
	n1=stonum(s,radix); // 将已知radix的数转化为10进制 
	s=tag>1?s1:s2; // 把s赋上另一个数 
	
	/*下面开始去找所求数中所有位数最大的那位,因为所求radix至少比它大*/ 
	long long int max=-1;
	for(int i=s.size()-1;i>=0;i--){
		if(isalpha(s[i])&&s[i]-87>max)
		max=s[i]-87;
		else if(!isalpha(s[i])&&s[i]-'0'>max)
		max=s[i]-'0';
	}
	
	long long int l=max+1>2?max+1:2; // radix至少是2,确定radix下界l 
	/* radix则取十进制下的第一个数和下界中最大的加一 */ 
	long long int r=n1>l?n1+1:l+1; 
	if(binsearch(l,r,n1,s)==-1) cout<<"Impossible";
	else cout<<binsearch(l,r,n1,s);	
	return 0;
}
原文地址:https://www.cnblogs.com/A-Little-Nut/p/8194793.html