PAT A1010.Radix 二分法

PAT A1010.Radix 

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

算法笔记实战指南P167

题意:

给2个数:N和M,给出N的进制,求出M的进制为多少时,才能与N相同,如果不存在这样的进制,给出“Impossible”

 N 和 M 都以字符串的形式给出,最多10个digits,从‘0’-‘9’,‘a’-‘z’,代表0-35

注意:

1. 虽然M每位最大是35,但是M的进制可能大于36。

2. M 的进制应该比它的 每一位都大,所以至少是它的所有数位上的最大的数+1,而不是直接以1位L,(这是题目要求)

3. M的进制最大值 = max(M的进制最小值,N的十进制)+1

4. M需要遍历的进制较多,需要二分,将复杂度降到O(log N) ,其中N = M的进制最大值 - M的进制最小值

5. 用上long long , 而且这样也会溢出,因此,转换为十进制后小于N,可能是进制太小,也可能是溢出造成小于0

代码如下:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 
 9 char n[15],m[15];
10 
11 int charToInt(char c)
12 {
13     if(isdigit(c))
14         return c-'0';
15     return c-'a'+10;
16 }
17 
18 // 注意:ans 可能会超过LL的范围,溢出,此时返回值小于0
19 LL toDecimal(LL radix, char a[]){
20     LL  ans = 0;
21     for(int i = 0;a[i];i++){
22         ans = ans * radix + charToInt(a[i]);
23     }
24     return ans;
25 }
26 
27 // 题目要求了进制必须大于每一位数字,这里查找最小的进制
28 int findMinRadix(char a[]){
29     int ans = -1;
30     for(int i = 0;a[i];i++){
31         ans = max(ans,charToInt(a[i]));
32     }
33     ans++;
34     return ans;
35 }
36 
37 LL solve(LL l, LL r, LL x){
38     LL preJudge = toDecimal(r,m);
39     // 注意这里也可以不预先判断,但是如果预先判断了,一定要注意小于x不代表真的小,还可能是溢出
40     if(preJudge>0&&preJudge<x)
41         return -1;
42     LL mid;
43     while(l<=r){
44         // 防止 l + r 溢出
45         mid = l + (r-l)/2;
46         LL y = toDecimal(mid, m);
47         if(y==x)
48             return mid;
49         // 注意判断是否溢出,如果溢出,也代表选择的进制太大
50         if(y<0||y>x)
51             r = mid-1;
52         else
53             l = mid+1;
54     }
55     return -1;
56 }
57 
58 int main(){
59     int target, radix;
60     while(scanf("%s%s%d%d",n,m, &target, &radix)!=EOF){
61         char tmp[15];
62         if(target==2){
63             strcpy(tmp,n);
64             strcpy(n,m);
65             strcpy(m,tmp);
66         }
67         LL x = toDecimal(radix, n);
68         LL l = findMinRadix(m);
69         LL r = max(l, x)+1;
70         LL ans = solve(l,r,x);
71         if(ans==-1)
72             printf("Impossible\n");
73         else
74             printf("%lld\n",ans);
75     }
76     return 0;
77 }

 

转载于:https://www.cnblogs.com/pracneyman/p/9595018.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值