二分_1010 Radix (25 分)

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 tagis 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

第一、虽然这里的数字范围为0-9a-z,但是进制不只是到36进制,而是还有向上的可能性

第二、这里使用long long都会超出范围,但是题中的数据都没有超过long long,所以使用long long没有问题,在计算幂指数的时候可能出现超出long long范围,出现小于0的情况

第三、遍历的话,存在一组样例会超时,所以换用二分的方式

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
const int maxn = 10000;
int tag,radix;
char n1[15],n2[15];
map<char,int> num;

void Init()
{
    for(int i = 0;i <= 9;i ++) num['0'+i] = i;
    for(int i = 10;i <= 35;i ++) num['a'+i-10] = i;
}
ll _pow(ll a,ll b)
{
    ll ans = 1;
    while(b)
    {
        if(b & 1) ans *= a;
        a *= a;
        b >>= 1;
    }
    return ans;
}
ll Judge(char *s,int test_radix)
{
    if(test_radix == 1)
        return strlen(s);
    int len = strlen(s),_index = 0;
    ll sum = 0;
    for(int  i = len - 1;i >= 0;i --)
        sum += num[s[i]] * _pow(test_radix,_index++);
    return sum;
}
ll _binary_search(ll sum)
{
    int _max = 0,len = strlen(n2);
    for(int i = 0;i < len;i ++)
        _max = max(_max,num[n2[i]]);
    ll l = _max+1,r = max(l,sum);
    while(l <= r)
    {
        ll mid = (l+r) >> 1;
        ll ans = Judge(n2,mid);
        if(ans == sum) return mid;
        else if(ans > sum || ans < 0)    //因为上面计算可能超出ll范围,出现小于0的情况
            r = mid-1;
        else if(ans < sum)
            l = mid+1;
    }
    return -1;
}
int main()
{
    Init();
    scanf("%s%s",n1,n2);
    scanf("%d%d",&tag,&radix);
    if(tag == 2)
        swap(n1,n2);
    ll sum = Judge(n1,radix);
    ll ans = _binary_search(sum);
    if(ans == -1)
        printf("Impossible\n");
    else
        printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/li1615882553/article/details/84641309