二分进阶--在二分外面套一枚举

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分进阶--在二分外面套一枚举相关的知识,希望对你有一定的参考价值。

题目

在这里插入图片描述

题目解析

读完题目,我们可以很清楚的知道最后以好进制表示的n的结果,结果肯定是多数个1组成,即11111…(m进制) = n(10进制)。

总结步骤:

  1. 枚举1的长度。
  2. 通过二分法搜索对应的进制数。
  3. 通过mid对应的进制数得到1序列的十进制数。
  4. 通过十进制数与n对比缩小二分搜索区间知道找出对应的进制。

对于强类型语言按照上述方式进行计算肯定会溢出。。
为了防止溢出需要对枚举的范围进行限制,由数学推导课得出,1的序列长度不会超过log2(n),进制数也不会超过k = pow(n,1/1的长度)。而弱类型语言不需要关心这些。。。毕竟应该不会溢出。。。(如python)

解题代码

class Solution {
public:
//该题是通过二分各种进制,由于所有的数字都是1则可得到相应的10进制结果,然后与num(需要求最小好进制的书)进行比较来进一步得到二分区间。
  string smallestGoodBase(string n) {
    long long int num = atoll(n.c_str());
    //外层循环枚举1的长度
    for (int m = log2(num); m >= 1; m--) {
//内层根据1的长度和二分枚举的进制得出相应的数字sum,然后根据sum与num的关系缩小二分区间
      long long l = 2, r = powl(num, 1.0 / m) + 1, mid, sum;
      while (l < r) {
        mid = (l + r) / 2;
        sum = 1;
        for (int j = 0; j < m; ++j) {
          sum = sum * mid + 1;
        }
        if (sum == num) {
          return string(to_string(mid));
        }
        else if (sum < num) {
          l = mid + 1;
        }
        else {
          r = mid;
        }
      }
    }
    return "";
  }
};

以上是关于二分进阶--在二分外面套一枚举的主要内容,如果未能解决你的问题,请参考以下文章

AcWing 1945. 奶牛棒球(枚举+二分)

寒假week1---二分查找(二分枚举)

FZU-2216 The Longest Straight (二分枚举)

POJ-1064.Cablemaster.(二分法枚举值求最优值)

用二分枚举答案题

另类二分--透过枚举得到本质--搜索左边界