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


题型分类:二分法、进制转换

题目大意:输出两个数,给出一个数的进制,判断另一个数在什么进制的情况下与前一个数相等。

解题思路:思路大致为,采用十进制作为桥梁,比较两个数是否相等。这题较难,已AC,接下来说一下这题的难点:

1.首先要想到得出进制的上下限,下限一定是比最小的元素要大1(比如 135a5 这个数,那么他的最小进制一定是11)。题目还写了,当答案不唯一时,输出最小的进制。这个告诉我们什么呢?首先我们先思考一下,什么时候会答案不唯一,只有在一个数字时,才会答案不唯一(比如说一个数是6,那么6这个数在7进制,8进制等等比7大的进制下,最后的十进制数都是6)。所以我们在选取上限时,有两个限制条件:条件一是上限要≥下限,这个是显然的;条件二是在答案不唯一时,要选取小的进制作为答案,所以第二限制条件是十进制的另一个需要比较的数,也就是代码段中的high = max(low, decimalN1)

2.二分法的写法要注意,并且在判断两个数是否相等时,如果数据变为负数,说明进制选取过大,超出了long long的表示范围

3.题目不能选用int,要用long long来保存数据,因为int的范围不够表示。


#include <iostream> 
#include <algorithm>
#include <string>
#include <cctype>

using namespace std;

long long toDecimal(string N, int radix);
long long getLow(string N);

int main(int argc, char** argv) {
	string N1, N2;
	int tag, radix;
	cin >> N1 >> N2 >> tag >> radix;
	if(tag == 2) swap(N1, N2); //当tag为2时,交换N1, N2,方便对数据进行统一处理 
	long long decimalN1 = toDecimal(N1, radix);
	long long low = getLow(N2), high = max(low, decimalN1); //分别计算出需要测定进制的上下限,计算上限时,上限一定≥下限,同时题目说明了,当进制不唯一时,输出最小的进制,所以还要加入N1的十进制数作为第二限定条件(此处是难点,多琢磨琢磨) 
	while(low <= high){ //数据量比较大,采用二分法来压缩时间 
		long long mid = (low + high) / 2; //mid即测试的进制 
		long long decimalN2 = toDecimal(N2, mid);
		if(decimalN2 < 0 || decimalN2 > decimalN1){ //难点:如果radix太大超出long long型的范围,会使decimalN2变为负数,此时也代表了进制过大 
			high = mid - 1;
		}else if(decimalN2 < decimalN1){ //进制选取的太小 
			low = mid + 1;
		}else{ //找到正确的进制,输出答案 
			cout << mid;
			return 0;
		}
	}
	cout << "Impossible";
	return 0;
}

long long toDecimal(string N, int radix){
	long long sum = 0;
	for(int i = 0; i < N.length(); i++){ //注意数字和字母转换成十进制时公式不一样 
		if(isdigit(N[i])) sum = sum * radix + N[i] - '0';
		else sum = sum * radix + N[i] - 'a' + 10;
	}
	return sum;
}

long long getLow(string N){ //获得进制的下限 
	char maxElement = '0';
	for(int i = 0; i < N.length(); i++){
		if(N[i] > maxElement) maxElement = N[i];
	}
	return (isdigit(maxElement) ? maxElement - '0' : maxElement - 'a' + 10) + 1; //最小进制一定比最大的元素大1 
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值