1010 Radix (二分查找)

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

 思路:

1、题目没给定n1,n2具体的取值范围,只给定了位数不超过10,不能随意用Int或long,因为进制没限定范围,可能取值从最低二进制到无穷进制都有可能。

2、考虑的做法是把n1,n2从字符串打成字符数组,再把每一位转成Int,一个大的数就变成了一个Int型的数组。

3、Java中根据Int型的数组,求它十进制的和,可以用BigInteger这个类。new BigInteger(String str,int radix),把radix进制表示的str这个数转成一个十进制的BigInteger,radix不写默认是十进制表示。

4、radix的下限是,至少比待求的这个数中每一位的最大值大1,上限是各个位按进制累加之后,其值不能大于已经给定具体大小的那个数。

5、用暴力算法的话,从下限遍历到上限,速度太慢,所以考虑用二分法。

6、程序中先用了暴力算法从radix的下限计算到了1000,1000之后用暴力算法,主要是为了调试用的。边界最小情况就是,待求的那个数只有一位,这时候,任何比这个数大的进制都可以,这时候就输出满足条件的最小的进制。比如 12 c 1 10,答案是13进制。

7、经过多次提交,判断出测试点7的radix,是在long的范围内。其实更严格的话,要把radix也作为一个BigInteger来算。

8、用一个或多个空格(包含制表符tab)分割一个字符串,str.spilt(\\s+);  s表示空格,+表示多个,双反斜杠。用 . 分割的话,要用双反义,即(“\\ . ”)。

import java.math.BigInteger;
import java.util.Scanner;

public class Demo2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner in = new Scanner(System.in);
		String n1 = in.next();
		String n2 = in.next();
		int tag = in.nextInt();
		String radix = in.next();

		char[] c1 = n1.toCharArray();
		char[] c2 = n2.toCharArray();

		int[] i1 = new int[c1.length];
		int[] i2 = new int[c2.length];

		for (int i = 0; i < c1.length; i++) {
			if (c1[i] >= 'a') {
				i1[i] = (10 + c1[i] - 'a');
			} else
				i1[i] = c1[i] - '0';
		}

		for (int i = 0; i < c2.length; i++) {
			if (c2[i] >= 'a') {
				i2[i] = (10 + c2[i] - 'a');
			} else
				i2[i] = c2[i] - '0';
		}

		if (tag == 1) {
			BigInteger num1 = toDecimal(i1, radix);
			judge(num1, i2);
		} else {
			BigInteger num2 = toDecimal(i2, radix);
			judge(num2, i1);
		}

	}

	private static void judge(BigInteger num1, int[] i2) {
		// TODO Auto-generated method stub
		int min_radix = 2;
		BigInteger sum = BigInteger.valueOf(0);
		int count = i2.length;
		for (int i = 0; i < i2.length; i++) {
			if (i2[i] >= min_radix)
				min_radix = i2[i] + 1;
		}
		long radix = min_radix;

		while (true) {
			BigInteger result = arr_sum(i2, radix);
			if (result.equals(num1)) {
				System.out.print(radix);
				break;
			} else if (result.compareTo(num1) > 0) {
				System.out.print("Impossible");
				break;
			} else {
				radix++;
				if (radix > 1000) {
					binarySearch(radix, i2, num1);
					break;
				}
			}

		}

	}

	private static void binarySearch(long radix, int[] i2, BigInteger num1) {
		// TODO Auto-generated method stub
		long lo = radix;
		long hi = Long.MAX_VALUE;
		radix = (hi-lo) / 2+lo;
		while (true) {
			BigInteger result = arr_sum(i2, radix);
			if (result.equals(num1)) {
				System.out.print(radix);
				break;
			} else if (result.compareTo(num1) > 0) {
				hi = radix - 1;
			} else {
				lo = radix + 1;
			}
			radix = (lo + hi) / 2;
			if (lo > hi) {
				System.out.print("Impossible");
				break;
			}
		}
	}

	private static BigInteger arr_sum(int[] i2, long radix) {
		// TODO Auto-generated method stub
		BigInteger sum = toDecimal(i2, radix + "");
		return sum;
	}

	private static BigInteger toDecimal(int[] num, String radix) {
		// TODO Auto-generated method stub
		BigInteger sum = BigInteger.valueOf(0);
		int count = num.length;
		BigInteger rad = new BigInteger(radix);
		for (int i = 0; i < num.length; i++) {
			BigInteger temp = rad.pow(count - 1);
			count--;
			sum = sum.add(temp.multiply(BigInteger.valueOf(num[i])));

//			sum = sum.add(BigInteger.valueOf(num[i] * (int) Math.pow(radix2, --count)));
		}

		return sum;

	}

}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值