1010. Radix (25)

本文介绍了一种解决特定进制数等式问题的方法,使用C++实现了一个程序,该程序通过二分查找法来确定使两个不同进制数相等所需的进制基数。文章讨论了数据类型的选取、避免溢出的策略以及使用二分法进行高效搜索的技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1010. Radix (25)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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>
#include<algorithm>
using namespace std;
long long  exchang(string s, long long  radix) {//把string转化为十进制数,注意可能会overflow,这时候返回的是负值
	int i,j;
	long long  temp;
	long long  count=0;
	for (i = 0; i < s.size(); i++) {
		if (s[i] >= '0'&&s[i] <= '9')
			temp = s[i] - '0';
		else
			temp = s[i] - 'a' + 10;
		for (j = 0; j < s.size() - i - 1; j++) {
			temp *= radix;
		}
		count += temp;
	}
	return count;
}
int main() {
	long long  i;//long long 类型,因为36^10只有longlong类型勉强能装下,但是进制数不止只有36,所以也可能会溢出overflow
	long long tag, min_begin;
	long long  radix;
	long long  temp, t1;
	string N1, N2;
	char  radix1;
	char max = '0';
	cin >> N1 >> N2 >> tag >> radix;
	if (tag == 2)
		swap(N1, N2);
	temp = exchang(N1, radix);
	for (i = 0; i < N1.size(); i++) {
		if (N1[i] > max)
			max = N1[i];
	}
	if (max >= '0'&&max <= '9')
		min_begin = max - '0';
	else
		min_begin = max - 'a' + 10;
	if (radix <= min_begin) {
		cout << "Impossible" << endl;
		return 0;
	}
	max = '0';
	for (i = 0; i < N2.size(); i++) {
		if (N2[i] > max)
			max = N2[i];
	}
	if (max >= '0'&&max <= '9')
		min_begin = max - '0';
	else
		min_begin = max - 'a' + 10;
	min_begin = min_begin+1;
	/*if (temp < 1000) {
		for (i = min_begin; i <= 1000; i++) {
			if (exchang(N2, i) == temp) {
				cout << i << endl;
				break;
			}
		}
		if (i == 1001)
			cout << "Impossible" << endl;
		return 0;
	}*/
	long long  j, k;
	long long  INF;
	INF = temp + 1;
	j = min_begin; k = INF;
	i = (j + k) / 2;
	while (true) {	//必须用二分法
		i = (j + k) / 2;
		t1 = exchang(N2, i);
		
		 if (temp < t1||t1<0) {
			k = i - 1;
		}
		else if (temp > t1) {
			j = i + 1;
		}
		else if (t1 == temp) {
			printf("%ld\n", (long)i);
			return 0;
		}
		if (j > k) {
			cout << "Impossible";
			return 0;
		}
	}
}
感想:

1.这道题我真的是血都做出来了,估计得花了有4个小时,就是有一个点一直答案错误,加大上限的话就会超时,最后是看网上的解答才弄出来的

2.用longlong类型,注意是否有溢出,在计算count的时候可能会溢出

3.二分法,因为值是关于进制数单调递增的,然后二分法的上限必须设置为第一个数加一,因为这样才能保证当数字只有一位的时候取得是最小的解

4.这道题的一些知识点:1.溢出后值是小于零的 2.a>>1相当于a/2 3.二分法注意循环的时候应该是min=mid+1,或者max=mid-1 而不是mid=min或者max, 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值