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;

}




 

你可能感兴趣的:(birt)