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

本文介绍了一种解决特定数学问题的方法——如何将n根蜡烛放置成美观的同心圆形状,通过枚举不同圆层数并使用二分查找确定每层蜡烛数,最终找到最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 ≤ ir. 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
 
//长春现场赛的一题,题目可以抽象出表达式如下:
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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值