A1010 Radix (25 分)PAT甲级真题(C++)【进制转换】题目详解 测试点分析

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

题意分析:

题目的意思其实很明确也很好理解,输入四个数:

N1 一个字符串(字符数<=10,在{0~9,a~z}中取)
N2 一个字符串(字符数<=10,在{0~9,a~z}中取)
tag 1代表radix是N1的进制,2代表radix是N2的进制
radix 进制数

假设我们取tag=1,题目就是要我们求出当N2是几进制时,它所表示的数的值与N1在radix进制下表示的数值相等。

基本思路:首先我们将已经知道进制的那个字符串所表示的数转换成10进制,这样进制统一后方便我们将两个字符串进行比较,实现函数为convertTo10。然后通过对进制之间的分析得出未知进制的数的进制范围 [low,high] ,再使用二分查找的方法找到使得两个数相等的那个进制,找不到则输出Impossible。

整体思路还是比较明朗的,具体可以看着代码理解

分析点1:进制的下界(最小值)

这个是就未知进制的这个数本身而言的,它所包含的字符显然每一个都是小于它的进制数的,如果大于等于的话就要进位了,所以它可以接受的最小进制数就是这些字符中最大的那个max再加1,即radix=max+1,也就是我们要找的进制的下界。

分析点2:进制的上界(最大值)

这个是要将两个字符串放在一起看的了,假设N1是已知进制为radix1的,我们要求N2的进制radix2,我们考虑一种情况,radix2=N1,此时如果N2只有一位数,而任何数的0次幂都为1,那么此时N2最大只能是N1-1,不可能满足N1=N2,所以radix2可以继续增大;进一步考虑radix2=N1+1,这时一位数的N1最大可以是N2,即刚好可以满足N1=N2,若是两位数的N2,则倒数第二位最小是1,所以无论最后一位取什么,始终是N2>=N1。

好了,这样一来我们就找到了这个临界点,就是当radix2=N1+1时,刚好可以满足N1=N2,也就是我们要找的N2进制的上界。

注意点!!!可能大家会遗漏,当进制转换后出现的溢出现象,此时值变为了-1,这就是进制数太大了导致的结果,所以要和 t>num 放在一起判断。要记得加上,不然会有测试点通不过~

代码如下:

#include
#include
#include
#include
using namespace std;
long long convertTo10(string n,long long radix)//将进制为radix的数转换为十进制
{
    long long sum=0;
    int index=0,temp=0;
    for(auto it=n.rbegin();it!=n.rend();it++)//rbegin是逆向迭代器,指向最后一个字符
    {
        temp=isdigit(*it)?*it-'0':*it-'a'+10;
        sum+=temp*pow(radix,index++);//系数乘以对应基数的index次幂
    }
    return sum;
}
long long find_radix(string n,long long num)//二分查找基数
{
    char it=*max_element(n.begin(),n.end());//找到一串数中的最大数,此为radix的最小值
    long long low=(isdigit(it)?it-'0':it-'a'+10)+1;//见分析1
    long long high=max(num,low);//最大radix若为num,则此时为10(radix进制下),见分析2
    while(low<=high)
    {
        long long mid=(low+high)/2;//二分查找提高效率
        long long t=convertTo10(n,mid);
        if(t<0||t>num)high=mid-1;
        else if(t==num)return mid;//返回查找到的radix
        else low=mid+1;
    }
    return -1;
}
int main()
{
    string n1,n2;
    long long tag=0,radix=0,result_radix;
    cin>>n1>>n2>>tag>>radix;
    result_radix=tag==1?find_radix(n2,convertTo10(n1,radix)):find_radix(n1,convertTo10(n2,radix));
    if(result_radix!=-1)
        cout<

运行结果如下:

A1010 Radix (25 分)PAT甲级真题(C++)【进制转换】题目详解 测试点分析_第1张图片

你可能感兴趣的:(#,PAT,c++,算法,数据结构,经验分享)