PAT (甲级) 1010 Radix (二分)

最开始以为是简单的暴力水题。额,实际上,是一道深刻的阅读理解题~~
题中 if the solution is not unique, output the smallest possible radix. 明显是将人忽悠到暴力方向去的。再加上题中给出的数据中每位数都是小于35(‘z’) 。嗯暴力一发,发现眼前一片绿_(:з」∠)_

后来想想,这题也没给出radix具体范围,并且可以证明答案一定是唯一的(假设已经有一个满足条件的进制,换个进制,值能和之前一样??? 不用多想答案具有唯一性!) 再一次佩服一波出题人的误导技能,题意用if条件句,emmm 没毛病,
非暴力的做法,radix显然与其值成非线性单调递增。那就是二分答案咯,二分区间?2 到 long long上限? 忽略十位的串求和 * logn 还是太大,会超时。但这只是个radix 基数,基数都过大,值肯定爆到银河系。判断保证基数不会大到令其值超long long,作二分的右剪枝。
关于二分区间,我看了网上思路,有很多版本都错了,没必要将上限和下限比较取较大作上限。已知串的值若小于带求串的最大数字,一定是Impossible!

最后我用的范围其实是 (待求串的最大数字+1 ,已知串的数值 + 1)

我学到了:很不习惯没设置数据范围的题,只能靠猜!感觉被题意坑了。还是不能小看了PAT, 以后认真点,可多长个心眼吧!~!

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
string s[3];
LL N[3],ans = -1;
inline int toNum(char c)
{
    if(c>='0' && c<='9') return c - '0';
    return c - 'a' + 10;
}
inline LL calRadix(string s, LL radix)
{
    LL ret = 0;
    LL t = 1;
    for(int i = s.length() - 1; ~i; i--)
    {
        ret += t * toNum(s[i]);
        t *= radix;
    }
    return ret;
}
inline bool judge(int tag, LL radix)
{
    N[tag] = calRadix(s[tag],radix);
    LL l = toNum(*max_element(s[tag^3].begin(),s[tag^3].end())) + 1;
    LL r = N[tag] + 1;
    while(l <= r)   //二分答案 
    {
        LL mid = (l + r) >> 1;
        //cout << l <<" " << mid << " " << r<< endl;
        N[tag^3] = calRadix(s[tag^3],mid);
        if(N[tag^3] < 0 || N[tag] < N[tag^3] ) r = mid - 1;
        else l = mid + 1;
        if(N[tag] == N[tag^3]) {
            ans = mid;
            return true;
        }
    }
    return false;
}

int main(void)
{
    //freopen("in.txt","r",stdin);
    cin >> s[1] >> s[2];
    LL tag, radix;
    cin >> tag >> radix;
    judge(tag,radix)? cout << ans: cout <<"Impossible";
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值