寒假训练--训练赛2--冰冰的生日

冰冰的生日

Time Limit: 1000MS Memory limit: 65536K

题目描述

冰冰马上要过生日啦!要知道,冰冰是个爱面子的人,所以他请了好多朋友来参加他的生日,因为生日上最重要的就是吃蛋糕啦!而且,蛋糕上的蜡烛也是重中之重,那么多朋友来了,如果蜡烛插得不好看,多丢人啊!所以冰冰想到了可以插成n(n>=1)个同心圆。那样的话美观又大方,当然了,圆心可以插可以不插,第i个圆上有k的i次方根蜡烛(1 ≤ i ≤ n),虽然满足这个条件的n和k有很多,但是,需要你输出n*k最小时n和k的值。如果有相同的n*k,那就输出n小的那个。

输入

多组测试数据,每组测试数据只包含一个数字s(18 ≤ s ≤ 10^12).

输出

对于每组测试,输出n和k。

示例输入

18
31
51

示例输出

1 17
4 2
1 50

提示

 n最小为1 ,当k为2时,s为10^12 == 2^50  n最大为50 ;    k最小为2 , 最大为10^12,在n的for循环里, 用二分来找合适的k值,并存下k*n最小时的值

来源

lwn

示例程序
#include <stdio.h>
int main()
{
    long long n , i , k , s , low , mid , high , sum , pn , pk , flag ;
    while(scanf("%lld", &s)!=EOF)
    {
        for(n = 1 ; n <= 50 ; n++)
        {
            low = 1 ;
            high = s ;
            mid = (low+high)/2 ;
            flag = 0 ;
            while(low < high)
            {
                k = 1 ;
                sum = 0 ;
                for(i = 1 ; i <= n ; i++)
                {
                    k *= mid ;
                    sum += k ;
                }
                if(sum == s || sum +1 == s)
                {
                    flag = 1 ;
                    break;
                }
                else if( sum + 1 < s)
                    low = mid +1 ;
                else
                    high = mid - 1 ;
                mid = (low+high)/2 ;
            }
            if(flag)
            {
                if(n==1)
                {
                    pn = n ;
                    pk = mid ;
                }
                else if(pn*pk > mid * n)
                {
                    pn = n ;
                    pk = mid ;
                }
            }
        }
        printf("%lld %lld\n", pn, pk);
    }
}

你可能感兴趣的:(寒假训练--训练赛2--冰冰的生日)