PAT 解題報告 1010. Radix (25)


1010. Radix (25)

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


題意

給定兩個數,其中單個位置上的數值范圍可以為 [0-z]。指定其中一個數的進制,試確定是否存在可能的進制讓兩數的實際值相等。

分析

此題沒有交代清楚 input 中 radix 的取值范圍以及對一位數有多重可能 radix 的情況如何輸出,坑比較大。下面是需要注意的點。

  • 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 溢出。於是需要用特定的 compare 函數,在累加的過程中判定是否大於另一個數。算是一種剪枝。
  • 5.還有一個條件:當兩個數都是 1 時,輸出 2.當兩個數相等且不為 1 時,輸出題中給出的 radix。

 

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <cstring>

 using namespace std;
//AC代碼
 char A[11];
 char B[11];
 long long least;

 long long num2Dec(char * p,long long radix)
 {
     long long len=strlen(p);
     long long m = 1;
     long long num = 1;
     long long sum = 0;
     for(long long i=len-1;i>=0;i--)
     {
         if(p[i]>='a'&&p[i]<='z')
             num= p[i] - 'a' + 10;
         else if(p[i]>='0'&& p[i]<='9')
             num=p[i] - '0';
         sum+=num*m;
         m*=radix;
     }
     return sum;
 }

 long long findLowRadix(char *p)
 {
     long long len=strlen(p);
     long long low=0;
     long long num;
     for(long long i=len-1;i>=0;i--)
     {
         if(p[i]>='a'&&p[i]<='z')
             num= p[i] - 'a' + 10;
         else if(p[i]>='0'&& p[i]<='9')
             num=p[i] - '0';
         if(num+1>low)
             low=num+1;
     }
     return low;

 }

 int compare(char* p,long long radix ,long long target)
 {
     long long len=strlen(p);
     long long m = 1;
     long long num = 1;
     long long sum = 0;
     for(long long i=len-1;i>=0;i--)
     {
         if(p[i]>='a'&&p[i]<='z')
             num= p[i] - 'a' + 10;
         else if(p[i]>='0'&& p[i]<='9')
             num=p[i] - '0';
         sum+=num*m;
         m*=radix;
         if(sum>target)  //avoid  overflow
             return 1;
     }

     if(sum>target)
         return 1;
     else if(sum<target)
         return -1;
     else
         return 0;

 }


 long long binarySearch(char *p,long long low,long long high,long long top)
 {
     long long mid = low;
     long long tmp;

     while(low<=high)
     {
         tmp = compare(p,mid,top);
         if(tmp>0)
         {
             high = mid-1;
         }
         else if(tmp<0)
         {
             low = mid +1;
         }
         else
             return mid;
         mid = (low + high)/2;
     }

     return -1;
 }


 int main()
 {
     long long tag;
     long long radix;
     long long target;
     long long least; // lowest possible radix
     long long most; // highest possible radix
     long long res;


     cin>>A;
     cin>>B;
     cin>>tag;
     cin>>radix;

     if(1==tag)
     {
         target=num2Dec(A,radix);
         least = findLowRadix(B);
         most = (target + 1 > least + 1) ? target +1 :least +1;
         res = binarySearch(B,least,most,target);
         if(res==-1)
             cout<<"Impossible"<<endl;
         else
             cout<<res<<endl;

     }
     else if(2==tag)
     {
         target=num2Dec(B,radix);
         least = findLowRadix(A);
         most = (target + 1 > least + 1) ? target +1 :least +1;
         res = binarySearch(A,least,most,target);
         if(res==-1)
             cout<<"Impossible"<<endl;
         else
             cout<<res<<endl;
     }

 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM