PAT 1010 Radix

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.

踩坑点:

① 一开始没注意到有多个满足的进制时,选最小的进制。

②注意二分法的上界不是36,应该是基准数转换为十进制加1!比如10 10000 0 10,输出应该是10000.(必须要加1,这点还没弄明白)

③注意二分搜索时left right以及最后输出的radix类型都要设置成long long

④转化为10进制时,由于radix是long long,可能会发生溢出,溢出判断:<0,此时radix应该减小

#include<cstdio>
#include<iostream>
#include<math.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<ctime>

using namespace std;

struct Bign {
	int d[15];
	int len;
	long long  radix;
	Bign() {
		memset(d, 0, sizeof(d));
		len = 0;
	}
};
Bign num_to_arr(string str) {
	Bign temp;
	int index = 0;
	temp.len = str.length();
	for (int i = 0; i < temp.len; i++) {
		if (str[i] >= '0' && str[i] <= '9')
			temp.d[temp.len - 1 - i] = str[i] - '0';
		else
			temp.d[temp.len - 1 - i] = str[i] - 'a'+10;
	}
	return temp;
}
long long arr_to_num(Bign a) {
	int len = a.len;
	long long r = a.radix;
	long long m=0;
	for (int i = len-1; i >=0; i--) {
		m = m * r + a.d[i];
		if (m < 0)
			return -1;
	}
	return m;
}

long long find_radix(Bign a, long long m,long long left, long long right) {
	
	while (left <right) {
		long long mid = (left + right) / 2;
		a.radix = mid;
		long long k = arr_to_num(a);
        if(k>=m||k==-1){
			right = mid;
		}
		else
			left = mid + 1;
	}
	return left;
}
int main() {
	string N1, N2;
	int flag;
	long long radix;
	cin >> N1;
	cin >> N2;
	scanf("%d %lld", &flag, &radix);
	Bign a = num_to_arr(N1);
	Bign b = num_to_arr(N2);
	long long m;
	long long  k;
	if (flag == 1) {
		a.radix = radix;
		m = arr_to_num(a);
		int max = b.d[0];
		for (int i = 0; i < b.len; i++) {
			if (b.d[i] > max)
				max = b.d[i];
		}
		k = find_radix(b, m, max + 1, m+1);
		b.radix = k;
		long long t = arr_to_num(b);
		if(t!=m)
			printf("Impossible");

		else
			printf("%d", k);

	}
	else {
		b.radix = radix;
		m = arr_to_num(b);
		int max = a.d[0];
		for (int i = 0; i < a.len; i++) {
			if (a.d[i] > max)
				max = a.d[i];
		}
		k = find_radix(a, m, max + 1, m+1);

		a.radix = k;
		long long t = arr_to_num(a);
		if (t != m)
			printf("Impossible");

		else
			printf("%d", k);
	}


	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值