2012 ACM-ICPC Asia Changchun Regional Contest – K:Yukari’s Birthday

  • Post author:
  • Post category:其他


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

//长春现场赛的一题,题目可以抽象出表达式如下:
k^1+k^2+k^3+...+k^r+p=n;(其中k>=2,r>=1,p为整数并且只能为0和1)。
由于n<=10^12,而k>=2,所以可以计算下r<37,那么可以直接以r最大为40考虑,枚举r,然后二分得到k,取最优。总时间复杂度为test*r*log2(n)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
using namespace std;
#define inf 0x3f3f3f3f
#define LL long long

int OK(double n,LL r,double k)
{
    double sum=0,e=1.0;
    LL i;
    bool flag=false;
    for(i=1;!flag&&i<=r;i++)
    {
        e*=k,sum+=e;
        if(sum>n) flag=true;
    }
    if(flag) return 0;
    else if(sum+1<n) return -1;
    else return 1;
}

int main()
{
    LL n,m,i,j;
    while(~scanf("%lld",&n))
    {
        LL k,r,sum=10000000000000000LL;
        for(i=1;i<=40;i++)
        {
            LL lef=2,rig=n,mid;
            LL ansk=-inf;
            while(lef<=rig)
            {
                mid=(lef+rig)>>1;
                int tmp=OK(n,i,mid);
                if(tmp==0) rig=mid-1;
                else if(tmp==-1) lef=mid+1;
                else if(tmp==1) ansk=mid,rig=mid-1;
            }
            if(ansk!=-inf)
                if(ansk*i<sum)
                    sum=ansk*i,k=ansk,r=i;
        }
        printf("%lld %lld\n",r,k);
    }
	return 0;
}



版权声明:本文为duanxian0621原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。