【Python】PAT甲级 A1010: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 ₁ and ₂, 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:
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:
Sample Output 1:
Sample Input 2:
Sample Output 2:
题目要点
本题 25 分,测试点共 20 个,为防止超时必须使用二分查找法,且需要考虑边界情况,难度较大,下面给出一种解题思路。
tag
的作用是指明N1
或N2
哪个数的进制已知,因此tag=1
或tag=2
是同一个问题,可以用条件语句分支讨论或者以tag=1
为准,当tag=2
时交换N1
和N2
。这里我们分析时认为tag=1
。
由于这道题比较复杂,所以进制转换的功能要封装成函数便于复用。实现任意进制到10进制的转换不难,如果使用ASCII码转换字符对应的数值时,注意数字、字母在ASCII不是连续存储的,需要判断一下。本文在 Python 中是使用index
方法,从0~z
的字符串中找到字符对应的下标位置,即为对应的数值。再用map
函数得到各位对应值的迭代器,通过列表生成器和sum
函数求出最后的十进制值,代码简洁清晰。
二分查找法是针对有序序列的,这道题之所以可以使用二分查找是因为N2
固定,随着radix
的增加,N2
所对应的十进制数值也就越大,构成一个递增序列。二分查找法需要的4个输入量:有序序列、目标值、low
、high
。目标值是N1
对应的十进制值,而low
和high
是这道题的难点,在易错分析中有详细分析。经过几轮查找后查找到与目标值相同的值时,当前指针位置也就是相应的radix
,输出mid
,即为最终结果;如果查找失败,那么输出-1
,在程序入口函数中判断,输出Impossible
。
易错分析
本题题设中没有给出一个具体的数值范围,因此 C/C++ 编写时要采用long long
形整数。Python 的整数长度足够长,不用考虑这类问题。
对于下界low
的确定,需要考虑输入的任意进制数值。比如对于2进制数,各个位上不可能出现2,对于10进制数,各个位上不可能出现10,而是进位,从0重新开始。因此找出输入的任意进制数值中最大的一位,再加1,即为low
。比如,输入105a
,最大的是a
,对应的值是10,那么这个数至少是个10+1=11进制数。(测试点0)
对于上界high
的确定,与下界类似。首先要考虑最大的可能性,即可能是N1
所对应的进制。然后,要考虑特殊的值,比如N1=0
时,其上界不可能为0
,至少是2
,或者说high
至少不能比low
小,否则循环直接跳出。因此上界要取二者最大值,即high=max(N1_dec, low)
。(测试点19)
Python 的数据类型是动态的,因此二分法计算中间元素的指针mid
时必须将最终结果取整,否则会得到一个小数值,以此为radix
计算输入数的十进制时会得到错误结果。
源代码