PAT 1010 Radix 进制转换+二分法

Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is “yes”, if 6 is a decimal number and 110 is a binary number.
Now for any pair of positive integers N1 and N2, your task is to find the radix of one number while that of  the other is given.

Input Specification:

Each input file contains one test case. Each case occupies a line which contains 4 positive integers:
N1 N2 tag radix
Here N1 and N2 each has no more than 10 digits. A digit is less than its radix and is chosen from the set {0-9, a-z} where 0-9 represent the decimal numbers 0-9, and a-z represent the decimal numbers 10-35.
The last number “radix” is the radix of N1 if “tag” is 1, or of N2 if “tag” is 2.

Output Specification:

For each test case, print in one line the radix of the other number so that the equation N1 = N2 is true. If the equation is impossible, print “Impossible”. If the solution is not unique, output the smallest possible radix.

Sample Input 1:

6 110 1 10

Sample Output 1:

2

Sample Input 2:

1 ab 1 2

Sample Output 2:

Impossible

题目意思:给你两个数N1和N2,并给出来其中一个数的进制作为基数radix,求另一个数的进制是多少时二者相等。第三个数tag如果是1表示radix是N1的进制,求N1的进制;如果是2表示radix是N2的进制,求N1的进制。

解题思路:需要N1和N2各自进制下表示的数相同,需要一个标准,可以都转换成十进制,需要一个函数convert,第一个参数是数值,第二个参数是进制,将这个数值转换为十进制。

数字表示使用[0-9,a-z],所以刚开始想的是另外一个进制的基数范围是1~36,这其实是不对的,基数范围是可以大于这个范围的,最大的情况其实是需要表示的该数的十进制,逐个遍历不是很理想,最佳方式是使用二分法。同时这道题还有一个坑点,如果使用当前进制转换得到的数值比另一个大,说明进制选大了,同时还要注意有可能产生溢出,也就是使用当前进制转换得到的数值小于0,原因也是进制选大了。

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
ll convert(string n,ll radix)//转换为10进制的函数
{
    ll sum=0;
    int index=0,temp=0;
    for(auto it=n.rbegin(); it!=n.rend(); it++) //通过反向迭代器遍历
    {
        if(*it>='0'&&*it<='9')
        {
            temp=*it-'0';
        }
        else
        {
            temp=*it-'a'+10;
        }
        sum+=temp*pow(radix,index++);
    }
    return sum;
}
ll find_radix(string n,ll num)
{
    ll low,mid,high,t;
    char c='0';
    for(auto it=n.begin(); it!=n.end(); it++)
    {
        if(*it>c)
        {
            c=*it;
        }
    }
    if(c>='0'&&c<='9')
    {
        low=c-'0'+1;
    }
    else
    {
        low=c-'a'+10+1;
    }
    high=max(low,num);
    while(low<=high)
    {
        mid=(low+high)/2;
        t=convert(n,mid);
        if(t<0||t>num)
        {
            high=mid-1;
        }
        else if(t==num)
        {
            return mid;
        }
        else
        {
            low=mid+1;
        }
    }
    return -1;
}

int main()
{
    string n1,n2;
    ll tag,radix,ans;
    cin>>n1>>n2>>tag>>radix;
    if(tag==1)
    {
        ans=find_radix(n2,convert(n1,radix));
    }
    else
    {
        ans=find_radix(n1,convert(n2,radix));
    }
    if(ans!=-1)
    {
        printf("%lld",ans);
    }
    else
    {
        printf("Impossible");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/wkfvawl/p/11385164.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值