• PTA (Advanced Level) 1010 Radix


    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 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、n2,给出其中一个数字tag的进制radix,要求判断是否存在某一进制可以使另一个数字与给定数字相等。

      为了方便运算,用字符串tn1、tn2记录输入的两个数字,字符串n1记录给定进制的数字,字符串n2记录未确定数字。用map<char, int > mp,记录每个字符所对应的数值,之后,可以先将给定进制的数字n1转化为10进制,n2的进制最小为其包含的最大数字+1记为leftn,且由于n2是整数,所以其进制最大不会超过n1的十进制与leftn中较大的一个+1,记为rightn。以leftn和rightn分别为左右边界二分所有进制,记mid为中点进制,将n2按mid进制转化为10进制与n1的十进制进行比较,如果n2较大证明mid取值过大,将rightn记为mid - 1;若小了,证明mid取值过小,leftn记为mid+1,若正好相等则找到答案。若无法找到某进制使得n1与n2相等,返回-1,如果返回的答案不为-1,输出答案,否则输出Impossible。

      AC代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 map<char, LL> mp;
     5 void init(){
     6     for(char i = '0'; i <= '9'; i++){
     7         mp[i] = i - '0';    //初始化0 - 9
     8     }
     9     for(char i = 'a'; i <= 'z'; i++){
    10         mp[i] = i - 'a' + 10;   //初始化a - z
    11     }
    12 }
    13 LL toDecimal(string a, LL radix, LL maxn){  //转化为10进制的函数,所转化后的数不会超过给出的maxn
    14     int len = a.size();
    15     LL ans = 0;
    16     for(int i = 0; i < len; i++){
    17         ans = ans * radix + mp[a[i]];
    18         if(ans < 0 || ans > maxn){  //如果数据溢出了或超过上限
    19             return -1;//返回-1
    20         }
    21     }
    22     return ans;//返回转化后的值
    23 }
    24 int cmp(string a, LL radix, LL n1){ //比较函数,用于比较n2的radix进制转化为10进制后与n1的十进制的大小
    25     LL n2_10 = toDecimal(a, radix, n1);
    26     //获得n2转化为10进制的值
    27     if(n2_10 == n1) //如果n2的10进制与n1的十进制相同证明该进制是我们要获得的进制,返回0
    28         return 0;
    29     else if(n2_10 < 0)  //如果toDecimal函数返回的n2小于0,证明n2在该进制下转化为十进制后大于n1的十进制
    30         return 1;   //进制过大返回1
    31     else if(n1 > n2_10) //如果n2在当前进制下转化为10进制小于n1的十进制
    32         return -1;  //进制过小返回-1
    33     else    //否则返回1
    34         return 1;
    35 }
    36 LL getRadix(string a, LL leftn, LL rightn, LL n1){
    37     //二分函数传入n2字符串,最小进制,最大进制,n1的十进制值
    38     while(leftn <= rightn){
    39         LL mid = (leftn + rightn) / 2;
    40         //获得中点
    41         LL flag = cmp(a, mid, n1);
    42         //判断终点进制n1与n2状态
    43         if(flag == 0)   //若比较函数返回了0,证明在mid进制下n1与n2相等
    44             return mid; //返回mid
    45         else if(flag == -1){    //进制过小
    46             leftn = mid + 1;
    47         }else if(flag == 1){    //进制过大
    48             rightn = mid - 1;
    49         }
    50     }
    51     return -1;
    52 }
    53 int getMaxNum(string a){    //获得n2中最大的数字
    54     LL ans = -1;
    55     for(string::iterator it = a.begin(); it != a.end(); it++){
    56         ans = max(ans, mp[*it]);
    57     }
    58     return ans;
    59 }
    60 int main(){
    61     init(); //初始化mp
    62     string tn1, tn2, n1, n2;
    63     int tag, radix;
    64     cin >> tn1 >> tn2 >> tag >> radix;
    65     //输入 tn1 tn2 tag radix;
    66     if(tag == 1){
    67         n1 = tn1;
    68         n2 = tn2;
    69     }else{
    70         n1 = tn2;
    71         n2 = tn1;
    72     }
    73     //n1记录已经确定进制的数字,n2记录未确定的数字
    74     LL n1_10 = toDecimal(n1, radix, INT_MAX);
    75     //将n1转化为10进制其上限为无穷大
    76     LL leftn = getMaxNum(n2) + 1;
    77     //获得n2的最小进制
    78     LL rightn = max(leftn, n1_10) + 1;
    79     //获得n2的最大进制
    80     LL ans = getRadix(n2, leftn, rightn, n1_10);
    81     //二分所有进制
    82     if(tn1 == tn2)
    83         printf("%d
    ", radix);
    84     else if(ans == -1){
    85         printf("Impossible
    ");
    86     }else{
    87         printf("%lld
    ", ans);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    深度优先搜索查找图中的所有连通分量
    广度优先搜索BFS-图
    深度优先搜索DFS-图
    稀疏向量算法
    zip函数
    函数(三)>>内置函数
    函数(二)
    面向对象1
    面向对象2
    函数(上)
  • 原文地址:https://www.cnblogs.com/suvvm/p/10119314.html
Copyright © 2020-2023  润新知