二分|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;
} 
posted @ 2020-04-05 10:03  fishers  阅读(201)  评论(0编辑  收藏  举报