PAT甲級-1010. Radix (25)進位制

kewlgrl發表於2018-02-19

1010. Radix (25)

時間限制
400 ms
記憶體限制
65536 kB
程式碼長度限制
16000 B
判題程式
Standard
作者
CHEN, Yue

Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The answer is "yes", if 6 is a decimal number and 110 is a binary number.

Now for any pair of positive integers N1 and N2, your task is to find the radix of one number while that of the other is given.

Input Specification:

Each input file contains one test case. Each case occupies a line which contains 4 positive integers:
N1 N2 tag radix
Here N1 and N2 each has no more than 10 digits. A digit is less than its radix and is chosen from the set {0-9, a-z} where 0-9 represent the decimal numbers 0-9, and a-z represent the decimal numbers 10-35. The last number "radix" is the radix of N1 if "tag" is 1, or of N2 if "tag" is 2.

Output Specification:

For each test case, print in one line the radix of the other number so that the equation N1 = N2 is true. If the equation is impossible, print "Impossible". If the solution is not unique, output the smallest possible radix.

Sample Input 1:
6 110 1 10
Sample Output 1:
2
Sample Input 2:
1 ab 1 2
Sample Output 2:
Impossible

給出兩個數N1和N2,Tag指出所給的Radix是第幾個數的進位制,計算出一個進位制使得N1=N2。

我的思路是先將給定進位制的數轉換成十進位制sum,記錄下未定數中各個位上最大的一位數mmax,然後根據“一個數的各個位上最大的數小於其進位制”在[mmax+1,sum+1]範圍內二分遍歷可能使得兩數相等的進位制。

(;´д`)ゞ這裡如果不二分的話,for迴圈在測試點7上限需要開到1e10,會直接超時爆掉…

#include<bits/stdc++.h>
using namespace std;
#define INF 0xfffffff
#define MAXN 1010
int a[MAXN],b[MAXN],mmax;
long long sum,res,ans;
void change10(string x,int r)//轉成10進位制
{
    memset(a,0,sizeof(a));
    int len=x.length();
    int cnt=len-1;
    sum=0;
    for(int i=0; i<len; ++i)
    {
        if(x[i]>='0'&&x[i]<='9')
            a[i]=int(x[i]-'0');
        else if(x[i]>='a'&&x[i]<='z')
            a[i]=int(x[i]-'a'+10);
        sum+=(pow(r,cnt)*a[i]);
        --cnt;
    }
}
bool tryR(string x)//依次嘗試各種進位制
{
    memset(b,0,sizeof(b));
    int len=x.length();
    mmax=0;
    for(int i=0; i<len; ++i)
    {
        if(x[i]>='0'&&x[i]<='9')
            b[i]=int(x[i]-'0'),mmax=max(mmax,b[i]);
        else if(x[i]>='a'&&x[i]<='z')
            b[i]=int(x[i]-'a'+10),mmax=max(mmax,b[i]);
    }
    long long low=mmax+1,high=sum+1;//上限至少要開到10000000000;
    long long mid;
A:
    while(low<=high)//二分處理
    {
        res=0;
        mid=(low+high)/2;
        int cnt=len-1;
        for(int i=0; i<len; ++i)
        {
            res+=(pow(mid,cnt)*b[i]),--cnt;
            if(res>sum||res<0)//越界
            {
                high=mid-1;
                goto A;
            }
        }
        if(res<sum) low=mid+1;
        else if(res>sum) high=mid-1;
        else if(res==sum)//&&mid>=mmax
        {
            ans=mid;
            return true;
        }
    }
    return false;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("F:/cb/read.txt","r",stdin);
//freopen("F:/cb/out.txt","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    string n,m;
    int t,r;
    cin>>n>>m>>t>>r;
    bool flag=false;
    if(t==1)
        change10(n,r),flag=tryR(m);
    else if(t==2)
        change10(m,r),flag=tryR(n);
    if(flag) cout<<ans<<endl;
    else cout<<"Impossible"<<endl;
}

相關文章