1. 程式人生 > >PAT甲級1010 Radix

PAT甲級1010 Radix

題目描述:
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 N ​1 ​​ and N ​2 ​​ , 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,tag=1,那麼radix代表n1的進位制數,否則radix代表n2的進位制數。已知其中一個的進位制數,判斷另一個數是不是該數某一個進位制下的數(都將他們轉化為10進位制數,看是否相等,相等就是存在某一個進位制),列印進位制數。

程式碼如下:

#include <iostream>
#include <cmath>
#include<cctype>
#include <algorithm>
using namespace std;
long ToDecimal(long a,string s)
{
    long sum=0,k=s.size()-1;
    for(int i=0;i<s.size();i++,k--){
        if(isdigit(s[i]))sum+=int(s[i]-'0')*pow(a,k);
        else sum+=int(s[i]-'a'+10)*pow(a,k);
    }
    return sum;
}
long find_radix(string n,long a)
{
    char it=*max_element(n.begin(),n.end());
    long low=(isdigit(it)?it-'0':it-'a'+10)+1;
    long high=max(a,low);
    while(low<=high){
        long mid=(low+high)/2;
        long s=ToDecimal(mid,n);
        if(s==a) return mid;
        else if(s>a||s<0) high=mid-1;
        else low=mid+1;
    }
    return -1;
}
int main()
{
    string n1,n2;
    long tag,radix,m,k;
    cin>>n1>>n2>>tag>>radix;
    k=tag==1?find_radix(n2,ToDecimal(radix,n1)):find_radix(n1,ToDecimal(radix,n2));
    if(k!=-1) cout<<k;
    else cout<<"Impossible";
    return 0;
}

來總結一下:
1)這個題不能用暴力遍歷的方法,測試點7會超時。。。所以只能用二分法!
2)用二分法就要涉及到上界和下界的問題,下界比較容易,就是n2中的最大數+1,上界不是很好想,是n1在十進位制中的數(tag=1)。無法說的很清,這個問題保留吧先。
3)溢位問題,當轉化的數存不下時,就會溢位,所以,在判斷的時候應該是s>a||s<0。
4)說一說max_element()的使用方法。
首先它是在標頭檔案< algorithm >中,而且返回的是迭代器。所以要加*,取出來的是最大值。