zoukankan      html  css  js  c++  java
  • 1010 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 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 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

    题意:使两个不同进制的数相等。

    Code:

    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    int arr[26] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
                    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 
                    31, 32, 33, 34, 35};
    
    int Tochange(char c) {
        int t;
        if (c > '9') {
            t = arr[c-'a'];
        } else {
            t = c - '0';
        }
        return t;
    }
    
    int StrToNum(string s, int n) {
        int ret = 0;
        int b, e = 1;
        reverse(s.begin(), s.end());
        for (int i = 0; i < s.length(); ++i) {
            b = Tochange(s[i]);
            if (b >= n) return -1;
            ret += b * e;
            e *= n;
        }
        return ret;
    }
    
    int main() {
        string N1, N2;
        int tag, t;
        int redix;
    
        cin >> N1 >> N2 >> tag >> redix;
    
        t = redix;
    
        int num1, num2;
        if (tag == 1) {
            num1 = StrToNum(N1, t);
            for (int i = 2; i <= 35; ++i) {
                num2 = StrToNum(N2, i);
                if (num1 == num2) {
                    cout << i;
                    return 0;
                }
            }
        } else {
            num2 = StrToNum(N2, t);
            for (int i = 2; i <= 35; ++i) {
                num1 = StrToNum(N1, i);
                if (num1 == num2) {
                    cout << i;
                    return 0;
                }
            }
        }
    
        cout << "Impossible";
    
        return 0;
    }
    

      

    这个代码通过了部分测试数据,有些数据返回的结果是Wrong Answer。


    看了一下别人的代码,发现上面出错的原因在于,在寻找基数的时候寻找的范围并不是在2~36之间,而是在2~+∞。如果还是用原来的遍历查找的话肯定是不行的,所以想到用二分法来查找。在用二分法来查找的时候要注意

        while (low <= high) {
    
        }

    while循环中是<=而不是<。

    还有就是35的10次方是一个很大的数字,开数据类型的时候要开成long long类型的。其实开成long long类型的之后还是会溢出,成为负数,所以在检测的时候会有这一句代码

    else if (temp < 0 || temp > n) high = mid - 1;
    

      

    Code:

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cctype>
    
    using namespace std;
    
    int arr[26] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
                    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 
                    31, 32, 33, 34, 35};
    
    int Tochange(char c) {
        int t;
        if (c > '9') {
            t = arr[c-'a'];
        } else {
            t = c - '0';
        }
        return t;
    }
    
    long long StrToNum(string s, long long n) {
        int b;
        long long ret = 0;
        long long e = 1;
        reverse(s.begin(), s.end());
        for (int i = 0; i < s.length(); ++i) {
            b = Tochange(s[i]);
            ret += b * e;
            e *= n;
        }
        return ret;
    }
    
    void findRedix(string s, long long n) {
        long long temp;
        char c = *max_element(s.begin(), s.end());
        long long low = Tochange(c) + 1;
        long long high = max(low, n);
        while (low <= high) {
            long long mid = (low + high) / 2;
            temp = StrToNum(s, mid);
            if (temp == n) {
                cout << mid;
                return ;
            }
            else if (temp < 0 || temp > n) high = mid - 1;
            else low = mid + 1;
        }
        cout << "Impossible";
    }
    
    int main() {
        string N1, N2;
        int tag, redix;
    
        cin >> N1 >> N2 >> tag >> redix;
    
        long long num1, num2;
        if (tag == 1) {
            num1 = StrToNum(N1, redix);
            findRedix(N2, num1);
        } else {
            num2 = StrToNum(N2, redix);
            findRedix(N1, num2);
        }
    
        return 0;
    }
    

      

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    第3、4、5讲
    .NetCore使用EF5操作Oracle,解决列自增序列绑定不生效的问题
    ASP.NET Core 之 Identity 入门(一)
    ORACLE NLS_DATE_FORMAT设置
    ORA12514遇到了怎么排查问题出在哪
    Oracle特殊字符查询语句
    ORA00821: Specified value of sga_target 3072M is too small, needs to be at least 12896M
    如何定位哪些SQL产生了大量的Redo日志
    Oracle定位对阻塞的对象或锁信息
    Oracle Undo和Redo的关系,区别及相关查询
  • 原文地址:https://www.cnblogs.com/h-hkai/p/12586636.html
Copyright © 2011-2022 走看看