题目大意:k^0+k^1+k^2+...+K^r=n,给你n让你求k和r,若有多组k和r取乘积最小的,若最小的乘积相同,取r值最小的(这里注意,蛋糕的中心可以不放蜡烛,因此k^0可以省略,所以判断的时候不要忘记)。
算法思路:有等比数列公式可得,当k取最小的2时,r最大不超过40,因为超过40,n就要超过12位了。那么只需要遍历r,然后对k在[2,pow(n,1/r)]区间内进行二分,求出答案即可。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define INF 1e13 long long n,kf,rf,flag,h,flag2; long long ansk,ansr,i; bool isOver,over; long long l,r,mid; long long flaga,sum; void binary() { for(int j=1;j<=40;j++) { l=2; isOver=false; r=(long long)pow((double)n,(double)1.0/(double)j)+1; while(l<=r) { sum=0; mid=(l+r)/2; flag=1; for(i=1;i<=j;i++) { flag=mid*flag; sum+=flag; } if(sum==n||sum==n-1) { isOver=true; break; } else if(sum>n) { r=mid-1; } else { l=mid+1; } } if(isOver) { if(flag>mid*j) { flag=mid*j; ansr=j; ansk=mid; } over=true; } } } int main() { while(scanf("%I64d",&n)!=EOF) { isOver=false; over=false; flaga=INF; binary(); // printf("%I64d %I64d\n",ansr,ansk); // if(over) // { printf("%lld %lld\n",ansr,ansk); // } // else // printf("1 %lld\n",n-1); } return 0; }