PAT二分法与穷举题目甲1010

该博客详细介绍了PAT甲1010题目的解题思路,涉及将两个正整数N1和N2转换成不同基数使其相等的条件。博主通过分析输入和输出规格,提出从2开始穷举并结合二分法来寻找解决方案,以降低时间复杂度。当基数计算导致数字超出给定范围或不唯一时,分别返回"Impossible"或最小基数。
摘要由CSDN通过智能技术生成

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 N1 and N2, 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-zrepresent 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

题意分析:

题目一共给出4个数字,前两个为要比较的数字,第三个为tag,若tag为1,则第四位数字也就是radix为第一位数字的基数,否则,为第二位数字的基数,如案例1:10为6的基数,所以6为十进制。

要求的为第二位数字的进制,使得两个数字得以相同,否则输出”Impossibel”

根据题目,我们可以分析出,要求的基数一定大于这个数字中最大的数字, ”A digit is less than its radix“
,如110,则基数一定大于1,所以我们可以从2开始找。

再者,若基数算出的数字超过了已给的数字后,再往下计算只会越算越大,所以,已给的数字是终点的可能之一,如6。

还有一种可能,max>num,此时为Impossible,max==num,此时若只有一位数字就为1,否则为Impossible。

这道题我一开始用了Long,因为题目中指出“Here N1 and N2 each has no more than 10
digits.”。

Long的长度是64位,若为十进制,则会溢出。

所以只能选用BigInteger来做。

在BigInteger内部是通过int 数组来表示和处理大数据的,理论上BigInteger可以接收任意长度的数字,基本等于我们机器的极限。
计算基数,我们通过穷举+二分,如果不使用二分法,则时间复杂度过不去。

import java.math.BigInteger;
import java.sql.Time;
import java.util.*;

/**
 * Created by Boolean on 2018/8/8.
 */
public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] num=new String[2];
        num[0] = scanner.next();
        num[1] = scanner.next();
        int tag = scanner.nextInt();
        long radix = scanner.nextInt();
        int tag_ = 0;
        BigInteger sum = convert(num[tag-1],BigInteger.valueOf(radix));
       // System.out.println(sum);
        if(tag==1)tag_ = 1;
        BigInteger max = BigInteger.ZERO;
        //先计算给出的数字
        for(int i=0;i<num[tag_].length();i++)
        {
            char ch = num[tag_].charAt(i);
            BigInteger t;
            if(Character.isDigit(ch))
            {
                t = BigInteger.valueOf(Character.getNumericValue(ch));
            }
            else
            {
                t= BigInteger.valueOf(((int)ch-87));
            }
            if(t.compareTo(max)==1)max = t.add(BigInteger.ONE);
        }
        //System.out.println(sum.toString());
        int flag = 0;
        BigInteger mid = BigInteger.ZERO;
       // System.out.println(high+" "+max_);
        BigInteger low = max;
        BigInteger high = max.max(sum);//high与num相比较
        //二分法,【high,low】
        while (low.compareTo(high)==-1||low.compareTo(high)==0)
        {
            mid = low.add(high).divide(BigInteger.valueOf(2));
            BigInteger res  = convert(num[tag_],mid);
            //System.out.println(res.toString());
            if(res.compareTo(sum)==1)
            {
                high = mid.subtract(BigInteger.ONE);
            }else if(res.compareTo(sum)==-1)
            {
                low = mid.add(BigInteger.ONE);
            }
            else
            {
                flag = 1;
                break;
            }
        }
        //输出
        if(flag==0)
        {
           System.out.println("Impossible");
        }
        else
        {
           System.out.println(mid);
        }
    }
    //用给出的基数与字符串,计算出结果
    private static BigInteger convert(String str,BigInteger radix)
    {
        BigInteger sum = BigInteger.ZERO;
       // System.out.println("???");
        for(int i=str.length()-1,count=0;i>=0;i--,count++)
        {
            char ch = str.charAt(i);
            if(Character.isDigit(ch))
            {
                sum = sum.add(radix.pow(count).multiply(BigInteger.valueOf(Character.getNumericValue(ch))));
            }
            else
            {
                sum = sum.add(radix.pow(count).multiply(BigInteger.valueOf((ch-'a'+10))));
            }
           // System.out.println(i);
        }
        return sum;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值