题意
有四个编号固定的贼要偷巧克力,第i个贼偷的数量的第i-1个人的k倍,k>1且为整数,但是未知
每个贼的包的容量最大都是n,也未知
现在告诉你,他们偷巧克力可能的方案数为m, 求最小的满足条件的n
- 样例:
如果m=2,即两种方案,那就一定是(1,2,4,8)和(2 , 4 , 8 , 16),n最小为16,最大为23
如果m=10,即十种方案,可知是不可能的,因为(8 ,16, 32,64)和(1 , 4,16, 64)是一定共存的
题解
可知:
n/8 + n/27 + n/64 + n/125+ … =m
所以,对每个数的立方预处理一下,直接二分二分的数据范围是关键,注意右边界right与立方数组cube[]的范围之间的联系
ps:代码的二分及极其不顺 0.0
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<queue>
#define INF 0x3fffffff
using namespace std;
typedef long long ll;
const int MAX_N = 1e6+10;
ll cube[MAX_N];
int main()
{
for(ll i=1;i<(ll)MAX_N;i++)
{
cube[i] = i*i*i;
}
ll n,m,k;
while(scanf("%I64d",&m)!=EOF)
{
ll res;
ll l = 8;
ll r = 1e16+1;
ll mid = (l+r)>>1;
int flag=0;
while(1)
{
ll ans=0;
for(int i=2;i<MAX_N;i++)
{
ll tmp = mid/cube[i];
if(tmp < 1 )
{
break;
}
if( ans > m)
{
break;
}
ans += tmp;
}
if(l >= r && ans !=m)
{
flag=0;
break;
}
if(l+1 == r && ans > m)
{
flag = 0;
break;
}
if(ans == m && (r-l)<=1)
{
res = mid;
flag = 1;
break;
}
else if(ans < m)
{
l = mid+1;
mid = (l + r)>>1;
}
else if(ans >= m)
{
r = mid;
mid = (l + r)>>1;
}
}
if(flag == 1)
{
cout<<res<<endl;
}
else
cout<<"-1"<<endl;
}
return 0;
}