PAT甲级1010 Radix个人理解

1010
柳神
最近都更新到本地了
&再见萤火虫&

1010 Radix (25)
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 
1and 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
结尾无空行

这道题自己做的时候没有头绪,代码是后面学习过后补上的,如果下面的个人解释没理解的话可以参考以上博主的文章

这道题的意思是:给两个数字A和B,再给出其中一个的进制数,求当A与B在同一进制下的值相等时,A的进制数是多少?

大思路:
将A、B两个数转化为十进制数,再将两个数进行比较,如果相等则输出此时A的进制数(假设题目已给出B的进制数),否则输出impossible
==**
做法:
1、确定输入数据类型。A和B有可能·包含数字和字母,所以A和B用字符串进行存储。标志和A的进制数没有给出大小且没有字母,但是由于题目提到A和B有着超过10位的数字,因此保险起见,使用较大的long long进行存储(int存储10^9)

2、首先将A转化为十进制数(这里其实选择多少进制数都可以,只是为了到最后两个数在同一进制下进行比较),转化方式从后往前遍历字符串,由于字符串中可能出现字符,所以还要特殊处理这个部分

3、暴力穷举进制数,试图转化B为十进制时等同于A。这里的难点是穷举的范围,首先是下界,由于题目给出的B是出于一定进制状态下的表示,因此B中所能出现的最大数字+1就是最小进制数(类似于十进制每个数位最大只能出现9),也就是说要使B的表示如题目给出的一样,他的进制数就必须如上;其次是上界,这里很巧妙的地方在于,以例子中的十进制6和110为例,假如此时的110的十进制等于6,那么110的进制数应该是多少呢?假设此时不是110,而是010(为什么要这么假设后面会说到),考虑到每一位的数字都是由进制数的次方乘以每一位上的数字,第二位的数字是乘以当前的进制数,也就是说二进制10中的1是乘以二进制中的2的一次方的,那么假如我们要使010等于十进制的6,那么010的进制数只能为六进制,又因为当010变大时(例如011、100),为了保持相等,进制数必须减小,因此当我们的数不是010而是110时,110的进制数必定会比010的进制数(六进制)要小,因此六进制可以看作是110的进制数的极大值(这里就解释了为什么上面要举例010)。
这个结论有普遍性,对每一个数字而言,他的进制数的上界都是另一个数字本身。

总结:进制转化的下界是B中所能出现的最大数字+1,上界是另一给出数字的本身。

而在实现上,有可能会出现上界 <= 下界的情况,此时就要把上界设置为较大值

4、将暴力穷举优化为二分查找。由于进制数(也就是我们设置的上界和下界) 是有序的,因此可以使用二分查找,将原来穷举的O(n)的时间复杂度优化为O(logn)。
二分查找时间复杂度

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

long long toDecimal(string s,long long base){
    long long res = 0;
    int index = 0,temp = 0;
    for(int i = s.size() - 1;i >= 0;--i){
        temp = isdigit(s[i])?s[i] - '0':s[i] - 'a' + 10;
        res += temp * pow(base,index++);
    }
    return res;
}

long long find_radix(string str,long long d){
    char temp = *max_element(str.begin(),str.end());
    long long low = (isdigit(temp)?temp - '0':temp - 'a' + 10) + 1;
    long long high = max(d,low);
    while(low <= high){
        long long mid = (low + high) / 2;
        long long t = toDecimal(str,mid);
        if(t < 0||t > d){
            high = mid - 1;
        }
        else if(t < d){
            low = mid + 1;
        }
        else{
            return mid;
        }
    }
    return -1;
}

int main(){
    string a,b;
    long long flag,base;
    cin >> a >> b >> flag >> base;
    if(flag == 2){
        swap(a,b);
    }
    long long result_radix = find_radix(b,toDecimal(a,base));
    if(result_radix == -1){
        cout << "Impossible" << endl;
    }
    else{
        cout << result_radix << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值