hdu4430 枚举+二分

Yukari's Birthday

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4934    Accepted Submission(s): 1163


Problem Description
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 k i 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 ≤ 10 12.
 

 

Output
For each test case, output r and k.
 

 

Sample Input
18 111 1111
 

 

Sample Output
1 17 2 10 3 10
 

 

Source
2012 Asia ChangChun Regional Contest
 题目大意:让你在蛋糕上插蜡烛,最中心可以插一根或者两根,然后蛋糕可以看作若干个半径递增的同心圆,
在半径为i(1<=i<=r)的同心圆上需要等距插上k^i根蜡烛,然后现在给你n根蜡烛,问你当k和i分别取多少时
可以使得r*k最小。
思路分析:k最小取2,因此i能取得值非常少,大致也就是到40,当i确定的时候,我们可以发现,蜡烛数目是随着
k增加递增的,因此可以二分寻找k值,程序比较容易写,但是也容易wa,以为你二分是k的范围如果取得很大,那么
再进行计算k^i的时候就会出现爆long long 的情况,体现姿势的时候到了,一是你可以在累加之前判断下k^i是不是大于n
了,即sum_now*mid>n?不过这么写不好,写成n/sum_now
把二分范围确定的小一些2~n^(1/i)
代码:
#include 
#include 
#include 
#include 
using namespace std;
typedef __int64 ll;
ll n;
int main()
{
    while(scanf("%I64d",&n)!=EOF)
    {
        ll r=1,k=n-1;
        int i,j;
        for(i=2;i<=40;i++)
        {
            ll kl=2,kr=n;
            while(kl<=kr)
            {
                ll sum=0;
                ll mid=(kl+kr)>>1;
                ll sum_now=1;
                for( j=1;j<=i;j++)
                {
                     if(sum>n)
                     {
                         sum=n+1;
                         break;
                     }
                     if(n/sum_now<mid)
                     {
                         sum=n+1;
                         break;
                     }
                      sum_now*=mid;
                      sum+=sum_now;
                }
                if(sum==n||sum==n-1)
                {
                    if(mid*ir)
                    {
                        k=mid,r=i;
                    }
                    else if(mid*i==k*r&&i<r)
                    {
                        k=mid,r=i;
                    }
                    break;
                }
                if(sum>n||sum<0) kr=mid-1;
                else kl=mid+1;
            }
        }
        printf("%I64d %I64d\n",r,k);
    }
}

 

转载于:https://www.cnblogs.com/xuejianye/p/5707544.html

你可能感兴趣的:(hdu4430 枚举+二分)