PTA甲级-1010 Radix 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

一、题干大意在这里插入图片描述

给出两个字符串和其中一个字符串的进制,求出另一个字符串的进制,使两者的值相等。最后输出求出的进制,如果不存在这种进制就输出 “Impossible”

二、题解要点

  • 两个函数,一个用来进行进制转化,也就是把任意进制的字符串转化为十进制的数。另一个用二分法求出进制。
  • 一定要注意:在二分法求进制的过程中,求出的进制是有可能上溢的,如果不解决就只能拿15分。

三、具体实现

/**
*@Author:hhzheng
*@Date:2023/2/6  10:58
*@Filename:PAT甲级1010 Radix
*/

#include<iostream>
#include <string>
#include <cmath>
#include <cctype>
#include <algorithm>
using namespace std;

/**
 * 输入一个字符串、一个数(表示进制) 将这个字符串转换为该十进制的数
 * @param n
 * @param radix
 * @return
 */
long long turnDecimal(string n, long long radix) {
    long long theResult = 0;
    for (int i = n.size() - 1; i >= 0; --i) {
        if (n.at(i) >= '0' && n.at(i) <= '9') {
            theResult += (n.at(i) - '0') * pow(radix, n.size() - i - 1);
        }
        if (n.at(i) >= 'a' && n.at(i) <= 'z') {
            theResult += (n.at(i) - 'a' + 10) * pow(radix, n.size() - i - 1);
        }
    }
    return theResult;
}

/**
 * 用二分法求出正确的进制 如果不存在返回-1
 * @param n
 * @param s
 * @return
 */
long long getRadix(long long n, string s) {
    char it = *max_element(s.begin(), s.end());
    long long low = (isdigit(it) ? it - '0': it - 'a' + 10) + 1; //找到可能的最小的进制
    long long high = max(n, low); //找到最大的可能的进制,比如说 1 1 1 10 这种情况就不能high = n了
    while (low <= high) {
        long long mid = (low + high) / 2;
        long long temp = turnDecimal(s, mid);
        if (temp < 0 ||temp > n) {  //一定要有temp < 0,因为在进制转化的时候有可能会上溢
            high = mid - 1;
        } else if (temp == n) {
            return mid;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}

int main() {
    string n1, n2;
    long long number1, number2, radix,answerRadix;
    int tag;
    cin >> n1 >> n2 >> tag >> radix;
    if (tag == 1) {
        number1 = turnDecimal(n1, radix);
        answerRadix = getRadix(number1,n2);
    } else {
        number2 = turnDecimal(n2, radix);
        answerRadix = getRadix(number2,n1);
    }
    if (answerRadix != -1){
        cout << answerRadix;
    }else{
        cout <<"Impossible";
    }
    return 0;
}


总结

全网的写法思路基本差不多,决定成败的就是在如何这个进制的上溢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值