1010 Radix (25分)暴力猜数or二分猜数

题目

https://pintia.cn/problem-sets/994805342720868352/problems/994805507225665536

题意

直接解释样例

数"6"是10进制,猜数"110"的进制数,使得6==110

数"1"是2进制,猜数"ab"的进制数,使得1==ab

Sample Input 1:

6 110 1 10

Sample Output 1:

2

Sample Input 2:

1 ab 1 2

Sample Output 2:

Impossible

思路&坑点

题目没有规定进制的上限,理论上N2的最大进制是int_N1(即N1的十进制的值)
如边界情况:N1:zzzzzz N2:10
因此需要用二分法猜这个进制数,参考柳神题解(long long溢出变负数了,太强了吧)
顺序暴力只T了一个点,能得24分,写起来方便,好像也不错。。。

code(顺序暴力版)

/***************************
        Hello World!
***************************/
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

ll ch_int(char x)
{
    if(x>='0' && x<='9') return x-'0';
    else return 10+(x-'a');
}

int main()
{
    string N1,N2;
    ll tag,radix;
    cin>>N1>>N2>>tag>>radix;
    if(tag==2) {
        string temp=N1;
        N1=N2;
        N2=temp;
    }
    ll int_N1=0;
    ll t=1;
    for(ll i=N1.size()-1;i>=0;--i)
    {
        int_N1+=ch_int(N1[i])*t;
        t*=radix;
    }

    //暴力猜 2-36进制。。。 //竟然没有规定进制的上线,啊啊啊啊啊啊啊啊啊
    for(ll ra=2;ra<=max(int_N1,36ll);++ra)
    {
        //能不能用ra进制??判断
        ll uuu=0;
        for(ll i=0;i<N2.size();++i)
        {
            if(ch_int(N2[i])>=ra) uuu=1;
        }
        if(uuu) continue;

        ll t=1;
        ll int_N2=0;
        for(ll i=N2.size()-1;i>=0;--i)
        {
            int_N2+=ch_int(N2[i])*t;
            t*=ra;
        }
        if(int_N2==int_N1) {
            //猜中
            cout<<ra<<endl;
            return 0;
        }
        else if(int_N2>int_N1) break;
    }
    cout<<"Impossible"<<endl;
    return 0;
}
/***************************
        The end!
***************************/

code(二分法)

/***************************
        Hello World!
***************************/
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

ll ch_int(char x)
{
    if(x>='0' && x<='9') return x-'0';
    else return 10+(x-'a');
}

int main()
{
    string N1,N2;
    ll tag,radix;
    cin>>N1>>N2>>tag>>radix;
    if(tag==2) {
        string temp=N1;
        N1=N2;
        N2=temp;
    }
    ll int_N1=0;
    ll t=1;
    for(ll i=N1.size()-1;i>=0;--i)
    {
        int_N1+=ch_int(N1[i])*t;
        t*=radix;
    }

    //二分猜
    ll ans=-1;
    ll left=0,right;
    //确定左边界
    for(int i=0;i<N2.size();++i) {
        if(ch_int(N2[i])>left) left=ch_int(N2[i]);
    }
    left++;
    //确定右边界
    right=max(left,int_N1);
    while(left<=right)
    {
        ll ra=(left+right)/2;

        //求int_N2
        ll t=1;
        ll int_N2=0;
        for(ll i=N2.size()-1;i>=0;--i)
        {
            int_N2+=ch_int(N2[i])*t;
            t*=ra;
        }

        //judge
        if(int_N2==int_N1) {
            //猜中,继续往左猜
            ans=ra;
            right=ra-1;
        }
        else if(int_N2>int_N1 || int_N2<0)//溢出变负数了,啊啊啊啊啊啊
        {
            right=ra-1;
        }
        else left=ra+1;
    }
    if(ans==-1) cout<<"Impossible"<<endl;
    else cout<<ans<<endl;

    return 0;
}
/***************************
        The end!
***************************/
posted @ 2020-08-02 23:43  liuyongliu  阅读(157)  评论(0编辑  收藏  举报