PAT甲级1010 Radix Java

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

注意:

  1. 使用二分查找的方法,因为当输入的进制过大时,例如输入:99999999 1 1 99999999时,如果从小到大开始查找就会花费很多时间,可以采用二分查找法,确定查找的上界和下界。
  2. 二分查找时,查找的下界很好确定,就是要确定进制的数字的最小进制,例如当要确定的数字为123时,则他的最小进制为4,输入的数字为abc时,最小进制为13,以此类推;查找的上界可以直接确定为已知进制的十进制大小。
  3. 当输入的数字或者进制过大时,可能会出现越界的现象,可以直接使用Java中的BigInteger类(但是我使用这个的时候出现了内存超限的提示还没有深究);然后可以使用long,但是要判断是否越界即在计算的过程中有没有出现小于0的情况;
  4. 在确定了上界和下界之后,二分查找之前,要将上界调整为上界和下界的最大值。如当输入为:1 1 1 10,按照一般方法确定的下界为2,上界为1,此时如果直接进行二分查找,会直接返回-1,所以此时要将上界确定为较大的2。

代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Radix {

    static long standard;

    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        String[] str = bufferedReader.readLine().split(" ");
        long standardRadix = Long.parseLong(str[3]);
        String toJudge;
        if (Integer.parseInt(str[2]) == 1) {
            standard = convertToRadix(str[0], standardRadix);
            toJudge = str[1];
        } else {
            standard = convertToRadix(str[1], standardRadix);
            toJudge = str[0];
        }
        long min = findMin(toJudge) + 1;
        long result = findResult(toJudge, min, standard);
        if (result == -1) System.out.print("Impossible");
        else System.out.print(result);
    }

    /**
     * 通过二分法找到对应的进制
     *
     * @return 找到则返回对应的数制,否则返回-1
     */
    private static long findResult(String toJudge, long left, long right) {
        long mid;
        right = Math.max(left, right);
        while (left <= right) {
            mid = (left + right) / 2;
            long temp = convertToRadix(toJudge, mid);
            if (temp == standard)
                return mid;
            else if (temp < 0 || temp > standard)
                right = mid - 1;
            else left = mid + 1;
        }
        return -1;
    }

    /**
     * 将每位数转换为对应的数字
     *
     * @param c 该位的字符
     * @return 代表的数字的大小
     */
    private static int convertToDigit(char c) {
        if (c < 58) return c - 48;
        else return c - 87;
    }

    /**
     * 找到二分的左边界
     * 即根据每位数的大小找到最小的进制,例如123,最小进制为4进制
     *
     * @param str 字符串表示的进制数
     * @return 最小进制
     */
    private static int findMin(String str) {
        int result = 0;
        for (int i = 0; i < str.length(); i++) {
            result = Math.max(result, convertToDigit(str.charAt(i)));
        }
        return result;
    }

    /**
     * 按照数制转换为对应的十进制数
     *
     * @param str   要转换的字符串
     * @param radix 数制
     * @return 转换后的十进制数的大小
     */
    private static long convertToRadix(String str, long radix) {
        long tempRadix = 1;
        long result = 0;
        for (int i = str.length() - 1; i >= 0; i--) {
            result += tempRadix * convertToDigit(str.charAt(i));
            tempRadix *= radix;
        }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值