PAT甲级1010 Radix

最开始想直接暴力,后来看网上题解说可以二分。

二分思路就是先将n1转化为10进制,二分搜索枚举n2的进制(low为n2的进制,hi为n1的10进制加1),将n2按照枚举的进制转换为10进制然后与n1的十进制进行比较。注意这里的二分是搜索最小的结果,因此第一次相等后仍然要向前面区间搜索看是否有更小的解。

坑点:

1、long long也可能会溢出,需要判断溢出

2、每一步二分的结果需要判断是否为符合条件

代码

#include <iostream>
#include <string>
#include <algorithm>


using namespace std;
typedef long long LL;

LL getDecimal(string s,int radix){
    LL ans = 0;
    if(radix == 10){
        for(int j=0;j<s.length();j++)
            ans = ans*10+(s[j]-'0');
    }else{
        LL time = 0;
        LL base = 0;
        LL mul = 1;
        for(int j=s.length()-1;j>=0;j--){
             //基数
             if(s[j]>='0'&&s[j]<='9')
                base = s[j]-'0';
             else if(s[j]>='a'&&s[j]<='z')
                base = s[j]-87;
      
            if(time == 0)
                mul = 1;
            else{
                mul = 1;
                for(int i=0;i<time;i++)
                    mul = mul*radix;
            }
            //cout<<"*"<<base<<" "<<mul<<" "<<time<<endl;
            time++;
            if(base < 0)    //溢出
                return -1;
            ans = ans + base*mul;
            if(ans<0)     //溢出
                return -1;
        }

    }

    return ans;
}

LL getLow(string s1){
    LL mmax = -1;
    for(int i=0; i < s1.length(); i++){
        if(s1[i]>='0'&&s1[i]<='9')
            if(mmax < s1[i]-'0')
                mmax = s1[i]-'0';
        else if(s1[i]>='a'&&s1[i]<='z')
            if(mmax < s1[i]-87)
                mmax = s1[i]-87;
    }
    return mmax;
}
int main()
{
    string n1,n2;
    LL flag,radix;
    cin>>n1>>n2>>flag>>radix;
    if(flag == 2)
        swap(n1,n2);
    LL cmp = getDecimal(n1,radix);
    LL hi = cmp+1;
    LL low = getLow(n2)+1;
    LL mid = 0;
    LL temp = 0;
    LL res = 0;
    bool flag2 = false;
    while(low <= hi){
        mid = low+(hi-low)/2; //防止溢出
        temp = getDecimal(n2,mid);
        //cout<<temp<<" "<<cmp<<endl;
        if(temp == cmp){    //证明有结果并将结果记录。万一前面没有结果则输出res
                //cout<<temp<<" "<<cmp<<" "<<mid<<endl;
            flag2 = true;    
            res = mid;
        }
        if(temp >= cmp || temp == -1) //判断溢出
            hi = mid - 1;
        else if(temp < cmp)
            low = mid + 1;

    }
    if(flag2)
        cout<<res<<endl;
    else
        cout<<"Impossible"<<endl;
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值