PAT 1010 Radix (25 分)

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 N
​1
​​ and N
​2
​​ , 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

题意

给你两个数字,数字最多不超过10位,而且每一位由0-9和a-z构成a-z代表十进制下的10到35。然后给你其中一个数的进制radix,tag=1代表是N1的进制,tag=2代表是N2的进制。然后让你求第二个数在什么进制下可能等于第一个数。若不存在则输出Impossible,若答案不唯一则输出最小的进制

思路

这题坑点很多,题面中没有说明要让你求得另一个数的可能进制范围,实际上这个进制可以非常大通过测试点可以看出其实还是没有超过long long范围的,甚至没有超过int范围。我们可以用二分来求这个进制,但是还是会爆long long,但是可以知道的是爆了之后的数要么还是大于给定的数或者是溢出之后变成负数,所以在二分的时候加上判断若为负则r=mid-1。还有一点是他若答案多解要求输出最小值。这个在二分的时候要是找到了一个答案那么先记录一下这个答案再r=mid-1继续二分下去。还有一点二分的时候左边界应该是他给你要求的这个数当中出现的最大的字符所对应的十进制数再+1,比如“10aef”,那么进制至少是从f也就是16进制开始的,小于16进制的答案应该舍弃。还有一点考虑 0 0 1 10这组数据。左边界应该从2进制开始而不是1进制

#include <bits/stdc++.h>
using namespace std;
char str[3][15];
long long num[3];
long long clac(int tag,long long radix)
{
    num[tag]=0;
    int len=strlen(str[tag]);
    for(int i=0; i<len; i++)
    {
        num[tag]*=radix;
        if(str[tag][i]<='9'&&str[tag][i]>='0')
            num[tag]+=str[tag][i]-'0';
        else
            num[tag]+=str[tag][i]-'a'+10;
    }
    return num[tag];
}
int main()
{
    int tag,radix;
    scanf("%s%s%d%d",str[1],str[2],&tag,&radix);
    char low;
    long long x=clac(tag,radix);
    tag=tag%2+1;
    int len=strlen(str[tag]);
    low=str[tag][0];
    for(int i=0; i<len; i++)
        low=max(str[tag][i],low);
    int flag=0;
    long long ans=9999999999999999;
    long long l=2,r=9999999999999999;
    if(low<='9'&&low>='0')
        l=low-'0'+1;
    else
        l=low-'a'+11;
    l=max(l,2LL);
    while(l<=r)
    {
        long long mid=(l+r)/2;
        long long mmid=clac(tag,mid);
        if(mmid==x)
        {
            flag=1;
            ans=min(mid,ans);
            r=mid-1;
            continue;
        }
        if(mmid>x||mmid<0)
            r=mid-1;
        else
            l=mid+1;
    }
    if(!flag)
        printf("Impossible\n");
    else
        printf("%lld\n",ans);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值