PAT-A-1010 Radix (25 分) 二分求解

举报
楚楚冻人玥玥仙女 发表于 2021/11/19 03:24:24 2021/11/19
【摘要】 1010 Radix (25 分) 题目传送门:PAT-A-1010 Radix (25 分) 一、题目大意 给出两个数n1,n2,还给出tag和radix,如果tag为1,则radi...

1010 Radix (25 分)

题目传送门:PAT-A-1010 Radix (25 分)

一、题目大意

给出两个数n1,n2,还给出tag和radix,如果tag为1,则radix为n1的进制,如果tag=2,则radix为n2的进制,求另一个数在什么进制下与这个数相等。

二、解题思路

首先:当tag=2时,swap(n1,n2)

此题有坑。我刚开始以为所求进制只是从2到36,因为输入的两个数中只有0-z,分别代表基数0-35,然鹅,提交了好多次,总是有四组数据过不了???,最后我发现题目并没有明确说明所求进制是36以内的。按理说进制就可能无限大,那么我们要怎么求出最小可能的进制呢。

我们可以分析一下,题目说了n1和n2长度不超过10,那么最大的数就是10个z,而10个z这种数至少是36进制,因为每一位数字不能超过其进制的基数。

36^10=3656158440062976,这个数已经超过了32int范围,但没有超过64位整数long long范围,我们可以是用long long 来存储十进制的值。

想要找到最小满足条件的进制,我们可以使用二分查找,二分的最小范围是n2这个数中最大位加1(也就是最小可能的进制数),二分的最大范围是n2这个数最大位加1的值与n1的十进制值的最大值。

然后进行常规二分操作即可。由于我二分写的不好,所以我每次在找到一个解的时候就记录下来,找到更小的就更新它,这样子我觉得会简单一点。当然那些代码写的好的人,直接用left记录最小解,不过我这样写经常会死循环调试半天,索性多花个变量记住解反而省事~

三、AC代码

#include <bits/stdc++.h>
using namespace std;
template<typename T = int>
T read(){
    T x;
    cin >> x;
    return x;
}
typedef unsigned long long ll;
ll getRadix(string s, int radix){
    ll ret = 0;
    for(int i = 0; i < s.size(); i++){
        int t;
        if(s[i] >= 'a'){
            t = s[i] - 'a' + 10;
        }else{
            t = s[i] - '0';
        }
        ret = 1LL*ret * radix + t;
    }
    return ret;
}
int main(){
    freopen("input.txt", "r", stdin);
    string n1 = read<string>(), n2 = read<string>();
    int tag = read(), radix = read();
    if(tag == 2) {
        swap(n1, n2);
    }
    ll x = getRadix(n1, radix);
    ll min_radix = 0;
    for(auto i: n2){
        if(isdigit(i)){
            if(i - '0' > min_radix)
            min_radix = i - '0' + 1;
        }else{
            if(i - 'a' + 10 > min_radix)
            min_radix = i - 'a' + 10 + 1;
        }
    }
    ll left = min_radix, right = max(x, min_radix);
    ll best = 0;
    while(left <= right){
        ll mid = (left + right ) >> 1;
        ll t = getRadix(n2, mid);
        if(t < 0 || t > x){
            right = mid - 1;
        }else{
            left = mid + 1;
            if(t == x){
                best = mid;//更新最优解
            }
        }
    }
    if(best){
        cout << best << endl;
    }else
    cout << "Impossible" << endl;

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 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
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

文章来源: blog.csdn.net,作者:爱玲姐姐,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jal517486222/article/details/97619258

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。