• PAT甲题题解-1010. Radix (25)-二分搜索


    题意:给出n1和n2,以及其中一个数的进制,问另一个数是多少进制的情况下,才会是两个数相等。不存在的话,则输出Impossible

    这题思路很简单,但是要考虑的比较多,在简单题里面算是比较好的。

    有两个注意点
    1.我被题目给骗了!!!以为最大进制只可能是36,所以在程序里就枚举2~36的进制,导致错了一大片样例
    最小进制下界low当然是n2的最大数字位+1
    最大进制上界high题目没有给出说明,但最大只可能为n1(前提n1>=low)。
    为啥不会超过n1呢,比如
    40 10 1 10
    很明显10是进制表示除“个位”外最小的了,那么只有当进制为40时,它才等于n1,如果进制再大,就肯定大于n1了。

    2.如果从low枚举到high,当high很大的时候,会很费时间,题目也设了一个样例会让你超时。
    所以这里需要二分搜索二进制k

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string.h>
    #include <cmath>
    using namespace std;
    char n1[20],n2[20];
    int t,r;
    long long tmp;
    
    /*
    val2为n2在k进制下的值
    val2<target,return -1
    val2==target,return 0
    val2>target,return 1
    */
    int cmp(long long*a,long long k,long long target,int len){
        long long val2=0;
        for(int i=0;i<len;i++)
            val2=val2*k+a[i];
        //val2可能存在溢出的问题,这里要注意。
        if(val2<0 || val2>target)
            return 1;
        if(val2<target)
            return -1;
        if(val2==target)
            return 0;
    }
    //二分搜索进制k
    long long binarySearch(long long *a,long long low,long long high,long long target,int len){
        long long l=low,r=high;
        long long mid;
        while(l<=r){
            mid=(l+r)/2;
            if(cmp(a,mid,target,len)==0)
                return mid;
            if(cmp(a,mid,target,len)<0){
                l=mid+1;
            }
            else{
                r=mid-1;
            }
        }
        return -1; //impossible
    }
    int main()
    {
        scanf("%s %s %d %d",n1,n2,&t,&r);
        if(t==2){
            swap(n1,n2); //交换一下,方便后面处理
        }
        char num[20];
        strcpy(num,n1);
        int len=strlen(num);
        long long val1=0; //转化成十进制
        for(int i=0;i<len;i++){
            if('0'<=num[i] && num[i]<='9')
                tmp=num[i]-'0';
            else if('a'<=num[i] && num[i]<='z')
                tmp=num[i]-'a'+10;
            val1=val1*r+tmp;
        }
        strcpy(num,n2);
        len=strlen(num);
        long long low=0;
        long long a[20]; //将n2的字符表示转化成数组存储
        for(int i=0;i<len;i++){
            if('0'<=num[i] && num[i]<='9')
                tmp=num[i]-'0';
            else if('a'<=num[i] && num[i]<='z')
                tmp=num[i]-'a'+10;
            a[i]=tmp;
            if(tmp>low)
                low=tmp;
        }
        low=low+1;
        long long high=max(low,val1)+1;
        long long ans=binarySearch(a,low,high,val1,len);
        if(ans==-1)
            printf("Impossible
    ");
        else
            printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    flex+spring3.0+blazds 数据推送整理版
    深入理解java虚拟机学习笔记1.
    一个netty序列化引起的思考。
    万年历
    面试理论题
    EF之Database First
    20120902 09:29 SQL、LINQ、Lambda 三种用法
    内容漂浮在图片上(div漂浮)
    生成订单号
    时间对比
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/6727939.html
Copyright © 2020-2023  润新知