【PAT】A1010 Radix (25分)--二分、进制转换

2 篇文章 0 订阅

做题链接

思路

把已知进制的字符串转换为十进制数N1
对另一个字符串str用二分法进行十进制数转换,初始二分区间为(m,h);其中m为最低进制:通过遍历str找到最大字符, 则进制为对应字符转换为数字+1;hmN1中较大者。

注意点

此题数的范围较大,采用long long类型
转换为10进制数时可能溢出, 当溢出时, 返回-1;
在二分过程中, 若某进制发生溢出, 则表明该进制下str转换成十进制数肯定大于N1, 故应减小进制,对应二分区间右边界更新为 right = mid -1;

AC代码

//2020.6.20
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;

typedef long long LL;
LL inf = (1LL<<63)-1;
string str, temp1, temp2;
int tag;
LL r, N1 = 0, m;
LL max(LL a, LL b){
    return a>b ? a: b;
}
LL change(string s, LL radix){ // 把str看成radix进制的数, 再转换为10进制
	LL x, N = 0;
	for(int i=0; i<s.size(); i++){
		if(s[i]>='0' && s[i]<='9'){
			x = s[i] - '0';
		}
		else{
			x = s[i] - 'a' + 10;
		}
		N = N*radix + x;
		if(N > inf || N<-1) return -1;
	}
	return N;
}
void init(){

	string s;
	if(tag == 1){
		str = temp2;
		s = temp1;
	}
	else{
		str = temp1;
		s = temp2;
	}
	N1 = change(s, r);
	char cc = '0';
	for(int i=0; i<str.size(); i++){
		if(str[i]>cc){
			cc = str[i];
		}
	}
	if(cc>='0'&&cc<='9'){
		m = (LL)(cc - '0') + 1;

	}
	else{
		m = (LL)(cc - 'a' + 10) + 1;
	}


}

LL binary(LL left , LL right){
	LL mid;
	while(left <= right){
		mid = (left + right) / 2;
		LL x = change(str, mid);
		
		if(x == N1){
			return mid;
		}
		else if(x == -1 || x > N1){
			right = mid - 1;
		}
		else{
			left = mid + 1;
		}
	}
	return 0;
}
int main()
{
	cin>>temp1>>temp2>>tag>>r;
	init();
    LL h = max(m, N1);
	LL ans = binary(m,h);

	if(ans != 0){
		printf("%lld",ans );
	}
	else{
		printf("Impossible");
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值