最小好进制问题

最小好进制问题

思路及解法

假设正整数 n 在 k (k≥2) 进制下的所有数位都为 1,且位数为 m + 1,那么有:
在这里插入图片描述
我们首先讨论两种特殊情况:

(1)m=0,此时 n=1,而题目保证 n≥3,所以本题中m>0。
(2)m=1,此时 n=(11)k,即k=n-1>=2,这保证了本题有解
然后我们分别证明一般情况下的两个结论,以帮助解决本题。

结论一
在这里插入图片描述
注意到 (1)式右侧是一个首项为 1、公比为 k 的等比数列,利用等比数列求和公式,我们可以得到:
在这里插入图片描述
对公式进行变换的到了:
在这里插入图片描述
移项化简得到:

在这里插入图片描述
这个结论结论可以帮助我们限制m的最大值,本题中3 <= n <= 10¹⁸并且k >=2的,所以
在这里插入图片描述
结论二:
在这里插入图片描述

根基(1)式,可知
在这里插入图片描述
依据二项式定理可知:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
根据上面这个的公时可以知道到,在这里插入图片描述必然为一个小数,且k为在这里插入图片描述的整数部分
在这里插入图片描述这个结论帮助我们在 nn和 mm 已知的情况下快速确定 kk的值。
综上上述两个结论,依据结论一,我们知道m的取值范围在这里插入图片描述,且m=1时必然有解。因为醉着m的增大,k不断减小,所以只需要从到小检查每一个m的可能值,利用结论二快速算出对应的k值,然后校验计算出k值是否有效即可。如果k值有效,我们即可返回结果。在实际代码中,我们首先算出 m 取值的上界 mMax,然后从上界开始向下枚举 m 值,如果当前 mm 值对应的 kk 合法,那么我们即可返回当前的 kk 值。如果我们一直检查到 m=2m都没能找到答案,那么此时即可直接返回 m=1 对应的 k 值:n-1

代码

char * smallestGoodBase(char * n){//字符串指针
    long nVal = atol(n);//将n指向的字符转换成long类型数据
    int mMax = floor(log(nVal)/log(2));//算出m上阶,从m的最大值向下枚举m,floor向下去整,因为k>=2,所以时log(2)
    char* ret = malloc(sizeof(char)*(mMax + 1));//记录最小好进制的代码,申请mMax+1位代码
    for(int m = mMax;m>1;m--){
        int k = pow(nVal,1.0/m);//double pow(double x, double y) 返回 x 的 y 次幂 ,m次根下nVal
        long mul = 1,sum = 1;
        for(int i=0;i < m;i++){
            mul *= k;
            sum += mul;
        }
        if(sum == nVal){
            sprintf(ret,"%lld",k);//最小好进制时k进制
            return ret;
        }
    }
    sprintf(ret,"%lld",nVal - 1);//最小号进制时nVal-1进制
    return ret;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值