您的位置:首页 > 其它

zoj 3665 Yukari's Birthday(枚举+二分)

2013-08-21 21:34 507 查看
Yukari's Birthday

Time Limit: 2 Seconds Memory Limit: 32768 KB

Today is Yukari's n-th birthday. Ran and Chen hold a celebration party for her. Now comes the most important part, birthday cake! But it's a big challenge for them to place n candles
on the top of the cake. As Yukari has lived for such a long long time. Though she herself insists that she is a 17-year-old girl.
To make the birthday cake look more beautiful, Ran and Chen decide to place them like r ≥ 1 concentric circles. They place ki candles equidistantly on
the i-th circle, where k ≥ 2, 1 ≤ i ≤r. And it's optional to place at most one candle at the center of the cake. In case that there are a lot of different pairs of r and k satisfying these restrictions,
they want to minimize r × k. If there is still a tie, minimize r.

Input

There are about 10,000 test cases. Process to the end of file.
Each test consists of only an integer 18 ≤ n ≤ 1012.

Output

For each test case, output r and k.

Sample Input

18
111
1111

Sample Output

1 17
2 10
3 10

这题是周赛的时候做的,不过我赛后自己写还写了几个小时,能力不行啊,老是出错
这题算幂的时候最好调用系统的pow函数,算法一样调用pow的能比我的快几倍。这也是事后才发现的,因为不管我怎么优化就是比别人的慢许多
至于这个题目中所说的如果有相等的r*k取r最小的,我写出了r*k的表达式,对它求导之后发现它是关于k单调递增的,我直接从r最大时开始,这样第一个找到的k就是最小的一旦找到立马退出,可以A。至于到底有没有那种几个r*k相等的情况我也不能证明出来
#include<stdio.h>
#include<math.h>
double logn;
long long n;
long long fun(long long k,int i)
{
int j;
long long s=1,sum=0;
for(j=0;j<i;j++)
{
if(s>n/k)
return n+1;
s*=k;
sum+=s;
if(sum>n)
return n+1;
}
return sum;
}
int main()
{
int i,j,r,num;
long long minx,mink,minr,min,max,mid,ki,temp;
while(scanf("%lld",&n)!=EOF)
{
logn=log((double)n);
num=log((double)n)/log(2.0);
minx=n;
for(i=num;i>=1;i--)//枚举r
{
min=1;
max=n;
while(min<=max)
{
mid=(min+max)/2;
temp=fun(mid,i);
if(temp>n)
max=mid-1;
else if(temp<(n-1))
min=mid+1;
if(temp==n||temp==n-1)
{
if(minx>i*mid)
{
minx=i*mid;
mink=mid;
minr=i;
}
break;
}
}
}
printf("%lld %lld\n",minr,mink);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: