题意简述:给定一个正整数n,肯定存在基底k(k>2),使n在基底k的表示中所有位都是1,求出所有这样的基底中最小的一个。
输入:一个string,表示正整数n。
输出:一个string,表示满足条件的最小基底k。
示例:对于数13,其在基底3下的表示是111,小于3的基底都不满足,因此输出是3。
题解:
问题用数学描述,就相当于求解方程
n=km+km−1+...+k+1
,不难得到
km<n<(k+1)m
,因此
k<n√m<k+1
。于是对于一个特定的m,方程要么没有解,要么只有一个解
k=⌊n√m⌋
。而m的范围是知道的,最小为1,最大是满足
n√m≥1
的最大值。因此只需遍历范围内的m,计算当
k=⌊n√m⌋
时方程右边是否等于n(注意这里只能用累加的方法,使用等比数列的求和公式
(km+1−1)/(k−1)
的话,
km+1
有可能超出long long int的范围,发生溢出使判断发生错误),如果相等证明k是一个解。设置一个变量储存当前最小的k,求出更少的解更新该变量,最后返回该变量即可。
实现的算法复杂度是 O(m) ,实际上采用二分搜索的策略(因为m的范围其实已知)还可以降至 O(log(m)) 。
class Solution {
public:
string smallestGoodBase(string n) {
long long ori = stoll(n);
long long res = ori-1, bits = 2;
while(1) {
long long temp = floor(pow(ori, 1.0/bits));
if(temp <= 1) break;
long long tempori = 0,tempr = 1;
for(int i = 0;i <= bits;i++) {
tempori += tempr;
tempr *= temp;
}
if(ori == tempori)
res = temp;
bits++;
}
return to_string(res);
}
};