1010 Radix (25 分)

该博客介绍了如何利用进制转换和二分查找法解决比较两个不同进制数字大小的问题。首先,定义了将字符转换为数字的函数,然后将未知进制数字转换为十进制。通过比较十进制数并采用二分查找法,找到了使两个数字相等的未知进制。最后,给出了完整的C++代码实现,并在main函数中演示了其应用。

在这里插入图片描述

///本题关键是确定进制的上限,可以有很大很大,故而设为long long类型
///进制转换和二分查找法是本题的解决方法

#include<bits/stdc++.h>
using namespace std;

///字符转化为数字
int charToInt(char ch)
{
    int rs= 0;
    if(ch >= '0' && ch <= '9')
    {
        rs = ch - '0';
    }

    if(ch >= 'a' && ch <= 'z')
    {
        rs = ch - 'a' + 10;
    }

    return rs;
}

///化为十进制数
long long changeToDecimal(string s,long long radix)
{
    long long result = 0;
    for(int i = 0; i < s.length(); i++)
    {
        result = result*radix + charToInt(s[i]);
    }

    return result;
}

///比较n1与n2在十进制下的大小,此函数可避免运行超时
int compare(long long n1, string n2, long long radix)
{
    long long sum = 0;
    for (int i = 0; i < n2.length(); i++)
    {
        sum = sum * radix + charToInt(n2[i]);
        if (sum > n1) ///重点,避免运行超时
        {
            return 1; /// n1 < n2
        }
    }
    if (sum > n1)/// n1 < n2
    {
        return 1;
    }
    else if (sum < n1) /// n1 > n2
    {
        return -1;
    }
    else ///相等
    {
        return 0;
    }

}

///二分查找,十进制数与未知进制数相等时的进制
long long Binary_Search(long long n,string p)
{
    ///step1:未知进制数的进制下界(每个位置数字的最大值+1)
    ///上界:max(n1的十进制,p的下界)+1;

    int max = 0;
    for(int i = 0; i < p.length(); i++)
    {
        if(max < charToInt(p[i]))
        {
            max = charToInt(p[i]);
        }
    }

    long long low = (long long)max + 1;///记录最小的进制;
    long long high;///记录最大进制;

    if(n > low)
    {
        high = n + 1;
    }
    else
    {
        high = low + 1;
    }
    long long mid;///中间数

    ///step2:二分查找
    while(low < high)
    {
        mid = (low + high)/2;
        if(compare(n,p,mid) == 0)///(n == changeToDecimal(p,mid))
        {
            return mid;
        }
        else if(compare(n,p,mid) == 1)///(n < changeToDecimal(p,mid))
        {
            high = mid;   ///while中是low <= high时,为mid-1;此处是low < high;但按照书中一模一样的写法,只能得24分
        }
        else
        {
            low = mid;    ///while中是low <= high时,为mid+1;此处是low < high
        }
    }

    return -1;
}

int main()
{
    string n1,n2,temp;
    int tag;
    long long radix;
    cin >>n1;
    cin >> n2;
    cin >> tag;
    cin >> radix;

    ///全部化为10进制比较
    long long sum1,sum2;///N1和N2化为十进制的值

    if(tag==2) ///永远都是n1作为已知进制数字存在,n2作为未知进制存在。
    {
        temp=n1;
        n1=n2;
        n2=temp;
    }

    sum1 = changeToDecimal(n1,radix);
    if(Binary_Search(sum1,n2) == -1)
    {
        cout << "Impossible" << endl;
    }
    else
    {
        cout << Binary_Search(sum1,n2) << endl;
    }

    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值