二分|Kickstart 2016 E- B. Beautiful Numbers
题目地址:https://code.google.com/codejam/contest/5264487/dashboard#s=p1
思路
1.小数据直接枚举radix
2.大数据思路:进制计算:n == r^(k-1) + r^(k-2) + ... + r + 1 ,因为这里r(进制)可以很大,k却很小,因为k最大为64 (2^64-1 <= n),所以考虑枚举k,二分r
总时间复杂度lognlognlogn
代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
bool check(ll n,ll k,ll radix){ //判n == r^(k-1) + r^(k-2) + ... + r + 1
ll sum = 0;
for(int i=0;i<=k-1;i++){
sum += pow(radix,i);
if(sum > n) return false;
}
return n == sum;
}
bool beautiful(ll n,ll x){ //判是否是beauty
while(n){
if(n % x != 1) return false;
n /= x;
}
return true;
}
ll cal(ll n,int k){
ll l = 1, r = n,mid = (l+r)>>1;
ll ans = 0x3f3f3f3f;
while(l<=r){ //二分radix
mid = (l+r)>>1;
if(check(n,k,mid)){
l = mid + 1;
if(beautiful(n,mid)) ans = mid;
}else r = mid - 1;
}
return ans;
}
ll solve(ll n){
ll ans = n-1;
for(int i=1;i<=64;i++){ //固定k
ans = min(ans,cal(n,i));
}
return ans;
}
int main(){
int t;
cin>>t;
for(int i=1;i<=t;i++){
ll input;
cin>>input;
cout << "Case #" << i << ": " << solve(input) << endl;
}
return 0;
}