PAT A1010 二分进制结合重点题

栏目: C++ · 发布时间: 5年前

内容简介:这道题而可以说是比较难的一道题,如果采用常规遍历,会出现时长或者溢出的问题;示例中给出的思路很值得借鉴;

PAT A1010 二分进制结合重点题

这道题而可以说是比较难的一道题,如果采用常规遍历,会出现时长或者溢出的问题;

示例中给出的思路很值得借鉴;

个人通过该示例有以下几个不同理解:

1.有时候两个不同进制的数对比,我们可以进行进制,转化十进制来进行比较;

2.对于有些枚举或者寻找问题,为了不进行枚举遍历,我们应该第一时间想到二分查找;

对于第一点,这个在题目中有所体现,我们都是将其转化为相应的十进制下,然后进行比较,看是否相同;

在这个途中,有个难点:对于未知进制数,我们应该如何推断,一定要注意溢出问题;

在本题目中,并没有对进制有限定,如果按照常规进制计算,就会发生int或这longlong溢出,这一点要注意;

而对于未知进制数,我们就可以让二分派上用场;

本题目的根本就是进制枚举,所以我们可以规定进制的上界和下界,从而通过二分来寻找一个进制,使得通过改进之转换的数和给定的数相同,来达到最终的结果;

那么问题又来了,上界和下界如何确定?

下界好说,下界就可以取整个数字序列中最大的数,加一就是下界。例如对于一个位15,最起码应该是16进制;

而对于上界,比较难以理解,上界取另一个数字在十进制下的值,加一就是上界;

举个例子说明一下,假如另一个数字十进制下是156,如果当前给出的值是1,那么多少进制可以让其和156相等,答案就是156进制,由于在二分查找下,我们输入的序列大原本序列1位,所以还需要+1;

详细代码如下所示:

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL inf=(1LL<<63)-1;
char n1[20],n2[20],temp[20];
int m[256];

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

LL convert2num10(char a[],LL radix,LL t){
    LL ans=0;
    int len=strlen(a);
    for(int i=0;i<len;i++){
        ans=ans*radix+m[a[i]];
        if(ans<0||ans>t)
            //ans<0为大到溢出的情况
            return -1;
    }
    return ans;
}
int findLargestDigit(char N2[]){
    int ans=-1;
    int len=strlen(N2);
    for(int i=0;i<len;i++){
        if(m[N2[i]]>ans){
            ans=m[N2[i]];
        }
    }
    return ans+1;
}

int cmp(char n2[],LL radix,LL t){
    int len=strlen(n2);
    LL num=convert2num10(n2,radix,t);
    if(num<0)
        return 1;
    if(t==num)
        return 0;
    else if(t>num)
        return -1;
    else
        return 1;
}

LL binarySearch(char n2[],LL left,LL right,LL t){
    LL mid;
    while(left<=right){
        mid=(left+right)/2;
        int flag=cmp(n2,mid,t);
        if(flag==0)
            return mid;
        else if(flag==-1)
            left=mid+1;
        else
            right=mid-1;
    }
    return -1;
}

int main(){
    init();
    int tag,radix;
    scanf("%s%s%d%d",n1,n2,&tag,&radix);
    if(tag==2){
        strcpy(temp,n1);
        strcpy(n1,n2);
        strcpy(n2,temp);
    }
    LL t=convert2num10(n1,radix,inf);
    //将N1从radix进制转化为10进制;
    LL low=findLargestDigit(n2);
    //low是序列中最大的数,也就是可以比较的最小进制,例如110,则合法的进制最小都未进制
    LL high=max(low,t)+1;
    //high是上界
    LL ans=binarySearch(n2,low,high,t);
    if(ans==-1)
        printf("Impossible\n");
    else
        printf("%lld\n",ans);
    system("pause");
    return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

从点子到产品

从点子到产品

刘飞 / 电子工业出版社 / 2017-1-1 / 49.00元

《从点子到产品:产品经理的价值观与方法论》以产品经理的方法论与价值观为主线,讲述了产品经理在从点子到产品的过程中应该考虑的问题、思考问题的思路,以及如何解决问题的方法。第一部分主要讲述从粗略的点子到具体的方案,要经历的步骤。第二部分主要讲述如何落实方案,以及如何进行用户研究、需求分析和产品设计。第三部分主要讲述在落实方案的过程中要掌握的方法和管理技巧。最后一部分主要讲述产品经理在工作和成长过程中要......一起来看看 《从点子到产品》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具