1010 Radix (25 point(s)) - C语言 PAT 甲级

1010 Radix (25 point(s))

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:

6 110 1 10

Sample Output:

2

题目大意:

N1 和 N2 各自不超过10位,如果 tag 为 1,则最后一个数字 radix 为 N1 的基数,如果标记为 2,则为 N2 的基数。数字 N1 和 N2 小于其基数,并从集合 {0-9,a-z} 中选择,其中 0-9 表示十进制数字 0-9,a-z 表示十进制数字 10-35。

设计思路:
  1. 两个数均转化为 10 进制数进行比较
  2. 寻找另一个数的基数时:
    • 确定基数的最小值和最大值
    • 二分法查找基数
  3. 当另一个数只有一位时,在任何大于它本身的基数下,其值均等于它自身:
    • 如果等于已知数,最小进制为自身加 1
    • 否则无解
编译器:C (gcc)
#include 
#include 
#include 
#include 

#define CBASE10(C) ((C) >= '0' && (C) <= '9' ? (C) - '0' : (C) - 'a' + 10)

long long convert10(char *s, long long radix);
long long minradix(char *s);
long long binsearch(char *s, long long n, long long rmin, long long rmax);

int main(void)
{
        long long tag, radix;
        char n1[11], n2[11], *s1, *s2;
        long long r, m1, rmin, rmax;

        scanf("%s %s %d %d", n1, n2, &tag, &radix);
        if (tag == 1) {
                s1 = n1;
                s2 = n2;
        } else {
                s1 = n2;
                s2 = n1;
        }

        m1 = convert10(s1, radix);
        rmin = minradix(s2);
        rmax = LLONG_MAX;
        if (strlen(s2) == 1) {
                if (m1 == rmin - 1)
                        printf("%lld", rmin);
                else
                        printf("Impossible");
        } else {
                r = binsearch(s2, m1, rmin, rmax);
                if (r != -1)
                        printf("%lld", r);
                else
                        printf("Impossible");
        }

        return 0;
}

long long convert10(char *s, long long radix)
{
        long long n, sum;
        for (sum = 0; *s; s++) {
                n = CBASE10(*s);
                if((LLONG_MAX - n) / radix < sum)
                        return -1;
                sum = sum * radix + n;
        }
        return sum;
}

long long minradix(char *s)
{
        char r;
        long long n;
        for (r = '0'; *s; s++)
                if (*s > r)
                        r = *s;
        return CBASE10(r) + 1;
}

long long binsearch(char *s, long long n, long long rmin, long long rmax)
{
        long long r, m;
        while (rmax >= rmin) {
                r = rmin + (rmax - rmin) / 2;
                if ((m = convert10(s, r)) > n || m == -1)
                        rmax = r - 1;
                else if (m < n)
                        rmin = r + 1;
                else
                        return r;
        }
        return -1;
}

你可能感兴趣的:(PAT,甲级)