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

题目来源: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;
}
发布了21 篇原创文章 · 获赞 1 · 访问量 1193

猜你喜欢

转载自blog.csdn.net/allisonshing/article/details/100896308