PAT 1010 Radix

2 篇文章 0 订阅
2 篇文章 0 订阅

解题思路:

  1. 将字符’0-9’和’a-z’映射到数组上面
  2. 定义字符串N转换成数的函数
  3. 定义比较两个字符串N1和N2转换后的数值的函数
  4. 编写二分查找函数,调用前面比较函数
  5. 查找字符串N2中各个位数上最大数
  6. 主函数里面确定N2的进制数最大和最小值

关键点:

  1. 进制数不止在0~35之间,可以非常大,超出int范围,所以建议使用 long long 作为数据类型。
  2. 在进制转换的时候,注意数据可能会溢出,所以比较两个转化后的数据需要考虑溢出的情况。
  3. 确定进制数是关键步骤,最小值应该就是N2各个位上最大值+1,最大值应该是比较最小值和N1,最后确定最大值+1。

代码如下:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;//替换类型名,方便编码
LL inf=(1<<63)-1;// long long 类型最大数 2^63-1 
LL map[256];// 将字符0-9 a-z映射为 0-35 


void init(){
    for(char c='0';c<='9';c++){
        map[c]=c-'0';
    }
    for(char c='a';c<='z';c++){
        map[c]=c-'a'+10;
    }
}


//将进制为radix的字符数组a[],转换为10进制数,upperBound是上界 
LL convertToDecimal(char N[],LL radix,LL upperbound){
    LL ans=0;
    int length=strlen(N);
    for(int i=0;i<length;i++){
        ans=ans*radix+map[N[i]];
        // if(ans<0||ans>upperbound){
        //     return -1;
        // }
        //溢出或超过N1的十进制
    }
    
    return ans;
}

//N2转化为十进制并与十进制的N1比较
int cmp(char N2string[],LL radix,LL N1){
    LL N2=convertToDecimal(N2string,radix,N1);
    if(N2<0){
        return 1;
    }
    if(N2<N1){
        return -1;
    }else if(N2==N1){
        return 0;
    }else {
        return 1;
    }
}


//二分求解N2的进制
int binarySearch(LL low,LL high,LL N1,char N2string[]){
    LL mid;
    while(low<=high){
        mid=(high+low)/2;
        int flag=cmp(N2string,mid,N1);
        if(flag==0){
            return mid;
        }else if(flag>0){
            high=mid-1;
        }else{
            low=mid+1;
        }
    }
    return -1;
}

//N2的最小进制是数位中的最大值加1
int findlow(char N2[]){
    int maxChar=-1;
    int len=strlen(N2);
    for(int i=0;i<len;i++){
        if(map[N2[i]]>maxChar){
            maxChar=map[N2[i]];
        }
    }
    return maxChar+1;
}

int main(){
    char N1[20],N2[20],temp[20];
    int tag;
    LL radix;
    scanf("%s %s %d %lld",N1,N2,&tag,&radix);
    if(tag==2){
        // 交换N1和N2,确保N1是已知进制的 
        strcpy(temp,N1);
        strcpy(N1,N2);
        strcpy(N2,temp);
    }
    init();
    LL n1=convertToDecimal(N1,radix,inf);//将N1转为十进制 
    LL low=findlow(N2); // N2的二分下界,最大数加1
    LL high=max(low,n1)+1;// N2的二分上界
    LL ans=binarySearch(low,high,n1,N2);
    if(ans==-1){
        printf("Impossible\n");
    }else{
        printf("%lld",ans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值