PAT甲级1010Radix25分/二分法猜进制转换/详细解读精准求出上限下限

题目要求根据r进制数n1,找出n2在何种进制下能等于n1。解题关键在于确定目标进制的上下限:下限为n2的最大位数的十进制数+1,以避免进位;上限为n1的十进制值与下限中较大的那个。在二分查找过程中注意处理溢出和个位数的情况。
摘要由CSDN通过智能技术生成

题目来源:https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536

代码参考:https://www.liuchuo.net/archives/2458

题目大意翻译:已知r进制的数n1,求n2在什么进制能等于n1

解法分析:

假如已经能想到先将n1换成十进制数,然后就该测试n2的进制了
难点:
1.目标进制的下限是n2的最大位数的十进制数+1。如果没有+1,那最大位数会进位。

2.目标进制的上限是n1的十进制和下限中较大那个。不要因为题目说两个数字用的数最大是z就以为进制最大是36。

  • 在n1的十进制大于下限的时候,n2为个位数的时候还是表示本身,但是一旦是两位数,就肯定超过n1的十进制数了(至少是n1加1)。
  • 在n1的十进制小于等于下限的时候,n1和n2肯定都是个位数,这个情况也不用继续求了。所求的可能的最小进制就是下限。

3.考虑进制转换后溢出成为负数。

//AC代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
long long  Convert(string n1,long long radix){
    int l1 = (int)n1.length();
    long long in1=0,j=1;
    for(int i=l1-1;i>=0;i--){
        if(isdigit(n1[i]))in1+=(long long)(n1[i]-'0')*j;
        else in1+=(long long)(n1[i]-'a'+10)*j;
        j*=radix;
    }
    return in1;
}
long long FindRadix(long long n1,string n2){
    long long res = -1;
    char it=*max_element(n2.begin(), n2.end());
    long long low=(isdigit(it)?it-'0':it-'a'+10)+1;//进制下限
    long long high=max(n1,low);//进制上限
    while(low<=high){
        long long mid=(low+high)/2;
        res = Convert(n2, mid);
        if(res==n1)return mid;
        else if(res<0 || res>n1)high=mid-1;//res<0 表示转换后溢出
        else low=mid+1;
    }
    return -1;
}
int main(){
    string n1,n2,n3;
    long long tag,radix,in1;
    cin>>n1>>n2>>tag>>radix;
    if(tag==2)swap(n1, n2);
    in1=Convert(n1,radix);
    long long guess=FindRadix(in1,n2);
    if(guess==-1)cout<<"Impossible";
    else cout<<guess;
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值