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
这道题好恶心,需要注意的地方主要有以下几个方面: 第一,N2 N1 每位的数字从0~35 选择,但radix 的范围却不一定;第二,int 范围偏小,必须用long long ;第三,搜索时,因为radix
可能非常大。计算出的value可能超越longlong 的范围,所以需要提前判断是否结束当前value的计算,我就是在此处跪了好久,干!第四,因为范围可能会很大,所以最好用二分查找,但是可能
涉及到有多个解得情况,所以要对二分法做特殊处理(此种情况都是单个数字的情况)
#include<stdio.h> #include <stdlib.h> #include <string.h> char *N1 ,*N2; long long minRadix, maxRadix,N2Length,N2Value[15]; long long value1,value2; int tag; long long radix1Value,radix2Value; inline int getValue(char a) { if(a >= 'a') return a - 'a' + 10 ; else return a - '0' ; } long long calculate(char * a,long long r) { int i, t ; int mylength = strlen(a); long long sum = getValue(a[mylength-1]); long long j = r; for (i = mylength -2 ;i>=0; i --) { t = getValue(a[i]) ; sum = sum + t*j ; j =j * r; } return sum; } int preProcess(char *a){ N2Length = strlen(a) ; int max = getValue(a[0]); N2Value[0] = max ; for (int i = 1;i < N2Length ;i++) { int temp = getValue(a[i]); if(max < temp) max = temp; N2Value[i] = temp; } return max; } bool isRadixExist() { long long low = minRadix; long long high = maxRadix; long long mid,k; long long sum, temp; mid = low ; while(low <= high) { sum = N2Value[N2Length-1]; temp = mid; for (k = N2Length-2; k>= 0;k--) { sum = sum + N2Value[k]*temp; if (sum > value1) break; temp*= mid; } if (sum > value1 ) { high = mid -1 ; }else if (sum == value1) { radix2Value = mid ; return true; }else{ low = mid +1 ; } mid = (low + high )>>1 ; } return false; } int main() { int flag = 0; N1 = (char *)malloc(sizeof(char)* 15) ; N2 = (char *)malloc(sizeof(char)* 15) ; if(N1 == NULL || N2 == NULL) return 0; char *pTemp; while (scanf("%s %s %d %lld",N1, N2,&tag, &radix1Value) !=EOF){ if(tag == 2) { pTemp = N1; N1 = N2; N2 = pTemp; } value1 = calculate(N1, radix1Value); minRadix = preProcess(N2) + 1 ; maxRadix = ( (value1 + 1) > (minRadix + 1) ? (value1 +1) : (minRadix +1) ); if (flag == 1) printf("\n"); else flag = 1; if (isRadixExist()) { printf("%lld", radix2Value); } else { printf("Impossible"); } } free(N1); free(N2); return 0; }