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

时间:2022-11-17 21:27:50

冰冰的生日

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