PAT (Advanced Level) Practice - 1010 Radix(25 分)

简介: PAT (Advanced Level) Practice - 1010 Radix(25 分)

题目链接:点击打开链接

题目大意:给定两个数,其中单个位置上的数值范围可以为 [0-z]。指定其中一个数的进制,试确定是否存在可能的进制让两数的实际值相等。(如果有多个答案,要求最小进制值)


解题思路:

1、input 中两个数字可以是 10 位数,虽然没有告诉 radix 的范围,但在9*10^10 10 1 200这个示例中,可以看到结果的 radix 也可以是很大的。从这个角度看,代码中将 radix 和两个数值都设定为 longlong 是合适的选择。

2、在计算另一个数的 radix 时,简单的遍历 [2, 1018]会超时。单调的区间很自然想到使用二分查找。

3、二分查找的上下界确定能减少耗时:下界选数字的所有位上的最大值+1;上界容易想当然的认为就是题中给定了 radix 的数的值。实际上,示例11 b 1 10就是一个反例,原因在于这个假设忽略了一位数的可能性,解决方案是在取给定 radix 的数值和下界中较大的那个数。

4、二分查找时,不可直接计算出某个 radix 下数的值,因为可能会 longlong 溢出。于是需要用特定的 cmp 函数,在累加的过程中判定是否大于另一个数。算是一种剪枝。

5、当两个数都是 1 时,输出 2。


AC 代码


/

#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
string a[3];
ll tag,radix,num;
int cal(char c)
{
    if(c>='0' && c<='9') return c-'0';
    else return c-'a'+10;
}
ll Any2D(string s, ll rdx)
{
    ll ans=0, tmp=1;
    for(int i=s.length()-1;i>=0;i--)
    {
        ans+=cal(s[i])*tmp;
        tmp*=rdx;
    }
    return ans;
}
int cmp(string s,ll rdx)
{
    ll ans=0, tmp=1;
    for(int i=s.length()-1;i>=0;i--)
    {
        ans+=cal(s[i])*tmp;
        if(ans>num) return 1;
        tmp*=rdx;
    }
    return ans==num?0:-1;
}
int maxR(string s)
{
    int ans=-1;
    for(int i=0;i<s.length();i++)
        ans=max(ans,cal(s[i]));
    return ans+1;
}
ll bs(int cur) // 此二分类型是:求最小的i,使得a[i] = key
{
    ll l=maxR(a[cur]), r=max(l,num), m, rs;
    while(l<r)
    {
        m=l+((r-l)>>1);
        rs=cmp(a[cur],m);
        if(rs==-1) l=m+1;
        else r=m;
    }
    return cmp(a[cur],r)==0?r:0;
}
int main()
{
    while(cin>>a[1]>>a[2]>>tag>>radix)
    {
        if(a[1]=="1" && a[2]=="1") puts("2");
//        else if(a[1]==a[2]) printf("%lld\n",radix);
        else
        {
            num=Any2D(a[tag],radix);
            int cur=tag==1?2:1, ans=bs(cur);
            if(ans) printf("%lld\n",ans);
            else puts("Impossible");
        }
    }
    return 0;
}
目录
相关文章
PAT (Advanced Level) Practice - 1057 Stack(30 分)
PAT (Advanced Level) Practice - 1057 Stack(30 分)
108 0
PAT (Advanced Level) Practice - 1057 Stack(30 分)
PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)
PAT (Advanced Level) Practice - 1068 Find More Coins(30 分)
112 0
PAT (Advanced Level) Practice - 1060 Are They Equal(25 分)
PAT (Advanced Level) Practice - 1060 Are They Equal(25 分)
102 0
PAT (Advanced Level) Practice - 1127 ZigZagging on a Tree(30 分)
PAT (Advanced Level) Practice - 1127 ZigZagging on a Tree(30 分)
122 0
PAT (Advanced Level) Practice - 1130 Infix Expression(25 分)
PAT (Advanced Level) Practice - 1130 Infix Expression(25 分)
126 0
PAT (Advanced Level) Practice - 1147 Heaps(30 分)
PAT (Advanced Level) Practice - 1147 Heaps(30 分)
119 0
PAT (Advanced Level) Practice - 1095 Cars on Campus(30 分)
PAT (Advanced Level) Practice - 1095 Cars on Campus(30 分)
130 0
|
存储 测试技术
PAT (Advanced Level) Practice - 1131 Subway Map(30 分)
PAT (Advanced Level) Practice - 1131 Subway Map(30 分)
112 0
PAT (Advanced Level) Practice - 1122 Hamiltonian Cycle(25 分)
PAT (Advanced Level) Practice - 1122 Hamiltonian Cycle(25 分)
117 0
PAT (Advanced Level) Practice - 1103 Integer Factorization(30 分)
PAT (Advanced Level) Practice - 1103 Integer Factorization(30 分)
99 0