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

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;
}



 

posted @ 2013-08-22 18:50  pangbangb  阅读(296)  评论(0编辑  收藏  举报