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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章