PAT甲级 1010 Radix

参考链接:点击打开链接

题目大意为,给定数a和数b以及数a的进制,求数b的进制,使数a与数b相等。

策略是采取二分查找法,确定的进制上下界中,查找一个进制,使其满足等式。

进制的下界容易确定,必然为数b中最大符号代表的数加上1。进制的上界为数a表示的值加上1。

1010 Radix (25)(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

实现代码如下:

#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

long long int charToInt(char ch);
long long int getSum(string n1,long long int radix);

long long int getMinVal(string n);

int main(){
	
	string n1,n2;
	long long int tag,radix;//注意都要是long long类型,否则可能会大数溢出
	cin>>n1>>n2;
	cin>>tag>>radix;
	
	if(tag == 2)
	{
		string temp;
		temp = n1;
		n1 = n2;
		n2 = temp;
	}
	
	long long int minVal = -1;
	minVal = getMinVal(n2);
	minVal += 1;//;最大符号数值加上一构成下限,比如二进制最高符号位是'1',所以必须得加上一
	
	long long int n1_sum = getSum(n1,radix);
	long long int maxVal = n1_sum+1;//上限是全部总和加一 
	
	while(minVal<=maxVal){
		long long int mid = (minVal + maxVal)/2;
		long long temp = getSum(n2,mid);
		if(n1_sum == temp)
		{
			cout<<mid;
			return 0;
		}
		//注意这里temp==-1时表示进制数太大造成temp变为负数,
		//此时要把进制数变小
		else if(n1_sum < temp || temp == -1)
			maxVal = mid - 1;
		else
			minVal = mid + 1;
	} 
	cout<<"Impossible";

	return 0;
} 

long long int charToInt(char ch){
	if(ch >= '0' && ch<= '9')
		return ch - '0';
	else
		return ch - 'a' + 10;//这里注意要加上10 
}

long long int getSum(string n1,long long int radix){//注意这里计算时要按每个位乘不同指数 
	long long sum = 0;
	long long num = 0,exe = 0;
	//从右到左算 
	for(int i=n1.size()-1;i>=0;i--)
	{
		num = pow(radix,exe);
		exe++;
		sum += charToInt(n1[i]) * num;
		if(sum < 0)//temp<0时表示进制数太大造成temp变为负数, 
			return -1; 
	}
	
	/*从左到右算 
	for(int i = 0;i<n1.size(); i++)  
    {  
        sum *= radix;  
        sum += charToInt(n1[i]);  
        if (sum < 0)  
        {  
            return -1;  
        }  
    }*/ 
	
	return sum;
}

long long int getMinVal(string n){
	long long int Val = 0;
	for(int i=0;i<n.size();i++)
			if(Val < charToInt(n[i]))
				Val = charToInt(n[i]);
	return Val;//返回最大符号数值比如二进制,最高符号位是'1',所以必须得加上一) 
}

方法二(简洁版):

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

long long int getSum(string n1,long long int radix);

int main(){
	
	string n1,n2;
	long long int tag,radix;//注意都要是long long类型,否则可能会大数溢出
	cin>>n1>>n2;
	cin>>tag>>radix;
	
	char it = tag == 1?*max_element(n2.begin(),n2.end()):*max_element(n1.begin(),n1.end());
	long long int minVal = isdigit(it)?it - '0' : it - 'a' + 10;
	minVal += 1;

	long long int n_sum = tag == 1?getSum(n1,radix):getSum(n2,radix);
	long long int maxVal = n_sum+1;//上限是全部总和加一 
	
	while(minVal<=maxVal){
		long long int mid = (minVal + maxVal)/2;
		long long temp = tag == 1?getSum(n2,mid):getSum(n1,mid);
		if(n_sum == temp)
		{
			cout<<mid;
			return 0;
		}
		//注意这里temp==-1时表示进制数太大造成temp变为负数,此时要把进制数变小
		else if(n_sum < temp || temp == -1)
			maxVal = mid - 1;
		else
			minVal = mid + 1;
	} 
	cout<<"Impossible";

	return 0;
} 

long long int getSum(string n1,long long int radix){//注意这里计算时要按每个位乘不同指数 
	long long sum = 0;
	long long num = 0,exe = 0;
	//从右到左算 
	for(int i=n1.size()-1;i>=0;i--)
	{
		num = pow(radix,exe);
		exe++;
		int val = isdigit(n1[i])?n1[i] - '0' : n1[i] - 'a' + 10;
		sum += val * num;
		if(sum < 0)//temp<0时表示进制数太大造成temp变为负数, 
			return -1; 
	}
	
	return sum;
}

猜你喜欢

转载自blog.csdn.net/qq_29762941/article/details/80997262
今日推荐