C++二分查找算法的应用:最小好进制
  Gjs2egXd7m0h 2023年12月06日 27 0


本文涉及的基础知识点

二分查找

题目

以字符串的形式给出 n , 以字符串的形式返回 n 的最小 好进制 。
如果 n 的 k(k>=2) 进制数的所有数位全为1,则称 k(k>=2) 是 n 的一个 好进制 。
示例 1:
输入:n = “13”
输出:“3”
解释:13 的 3 进制是 111。
示例 2:
输入:n = “4681”
输出:“8”
解释:4681 的 8 进制是 11111。
示例 3:
输入:n = “1000000000000000000”
输出:“999999999999999999”
解释:1000000000000000000 的 999999999999999999 进制是 11。
参数范围
n 的取值范围是 [3, 10^18]
n 没有前导 0

分析

值相等,进制越小,位数越多。进制最小是2,1018大约是264次方,放宽些,假定最大长度为70
求最小的k,也就是最大的位数对应的进制
主函数,从大到小尝试各位数能否存在好进制
Is函数利用二分法判断是否存k进制的m位1刚好等于n,如果存在则返回k,否则返回0。
由于n>=3,所以11一定是好进制。也就是本题一定有解。
Cmp函数:k进制的m个1和n的大小比较,n大返回正数,相等返回0,n小返回负数。llHas记录当前位的值。
注意:各值的范围

代码

class Solution {
 public:
 string smallestGoodBase(string n) {
 long long llN = 0;
 for (const auto& ch : n)
 {
 llN = (llN * 10 + ch - ‘0’);
 }
 for (int i = 70; i > 2; i–)
 {
 long long llRet = Is(i, llN);
 if (llRet > 0 )
 {
 return std::to_string(llRet);
 }
 }
 return std::to_string(llN-1);
 }
 long long Is(int m, long long n)
 {
 long long left = 2, right = n + 1;
 while (right - left > 0 )
 {
 const auto mid = left + (right - left) / 2;
 const auto llRet = Cmp(mid, m, n);
 if (0 == llRet)
 {
 return mid;
 }
 if (llRet > 0)
 {
 left = mid+1;
 }
 else
 {
 right = mid;
 }
 }
 return 0;
 }
 //k进制的m个1和n的大小比较,n大返回正数,相等返回0,n小返回负数
 long long Cmp(long long k, int m, long long n)
 { 
 long long llHas = 1;
 for (; m > 0; m–)
 {
 if (n < llHas)
 {
 return -1;
 }
 n -= llHas;
 if (m > 1)
 {// 最后一次llHas并不使用,所以越界不影响
 if (LLONG_MAX / k < llHas)
 {
 return -1;
 }
 llHas *= k;
 }
 }
 return n;
 }
 };

测试用例

template
 void Assert(const T& t1, const T& t2)
 {
 assert(t1 == t2);
 }template
 void Assert(const vector& v1, const vector& v2)
 {
 if (v1.size() != v2.size())
 {
 assert(false);
 return;
 }
 for (int i = 0; i < v1.size(); i++)
 {
 Assert(v1[i] ,v2[i]);
 }
 }int main()
 {
 Solution slu;
 string res;
 res = slu.smallestGoodBase(“470988884881403701”);
 Assert(res, std::string(“686286299”));
 res = slu.smallestGoodBase(“2251799813685247”);
 Assert(res, std::string(“2”));
 res = slu.smallestGoodBase(“13”);
 Assert(res, std::string(“3”));
 res = slu.smallestGoodBase(“4681”);
 Assert(res, std::string(“8”));
 res = slu.smallestGoodBase(“1000000000000000000”);
 Assert(res, std::string(“999999999999999999”));
 res = slu.smallestGoodBase(“1333”);
 Assert(res, std::string(“36”));
 res = slu.smallestGoodBase(“463381”);
 Assert(res, std::string(“463380”));//CConsole::Out(res);}


相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版

充满正能量得对大家说

闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。

墨家名称的来源:有所得以墨记之。

算法终将统治宇宙,而我们统治算法。《喜缺全书》

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开

发环境: VS2022 C++17

C++二分查找算法的应用:最小好进制_最小


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月06日 0

暂无评论

推荐阅读
  8Tw5Riv1mGFK   2024年05月01日   80   0   0 C++
  BYaHC1OPAeY4   2024年05月08日   56   0   0 C++
  yZdUbUDB8h5t   2024年05月05日   43   0   0 C++
  oXKBKZoQY2lx   2024年05月17日   57   0   0 C++
Gjs2egXd7m0h