HDU - 4430(二分)

33 篇文章 0 订阅
5 篇文章 0 订阅
/*
    HDU - 4430
    题目大意就是
    给你n个蜡烛
    要你围城r个同心圆,每个圆上的蜡烛数是k^i
    在圆的中心可以放1个蜡烛也可以不放
    问当r*k最小时,r和k分别是多少


    解题思路:
    我们可以枚举r然后找到符合条件的k
    计算r*k找到最小的哪一组


    当r最大,则k要最小即k==2
    2^0+2^1+2^2+...+2^40=2^41-1>10^12
    所以r最大就41,枚举r时枚举到41左右即可不用循环太多次
    另外当r=1,k=n-1时是所有n的一个通解
    即此题不存在无解的情况


    查找k的时候使用二分查找可以减少时间
*/
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#include<stdio.h>
#include<math.h>
#define ll long long
#define PI acos(-1)
using namespace std;
ll n;
ll work(ll k,int j)
{
    ll sum=0;//对k~k^j项求和
    ll ans=1;//求k的1~j次方
//此处说明一下,因为编译器的原因pow(10.0,2)会被某些编译器计算成99所以没有直接使用pow函数
    for(int i=1; i<=j; i++)
    {
        if(n/ans<k)//当k的某个次方数超过n时,就已经不满足要求了,所以设置一个标志后直接跳出
        {
            sum=n+1;//设置的标志,让sum出现一个不应该出现的值
            break;
        }
        ans=ans*k;//若符合要求,则计算k的i次方
        sum=sum+ans;//计算k的前i次方的和
        if(sum>n)//若sum已经大于蜡烛数则这个k不满足要求,直接跳出
            break;
    }
    return sum;
}
int main()
{
    while(cin>>n)
    {
        ll a=1,b=n-1;//设置一个通解
        for(int j=2; j<=45; j++)//对圈数循环
        {
            ll l=1,r=n;//二分查找设置左右
            ll mid;
            while(r-l!=1)//循环查找的条件
            {
                mid=(l+r)/2;
                ll sum=work(mid,j);
                if(sum==n||sum==n-1)//因为可以在中心摆放一个蜡烛,也可以不摆放所以二者满足其一即可
                {
                    if(mid*j<a*b)//若比以前求得的要小则保存下来
                    {
                        a=j;
                        b=mid;
                    }
                }
                if(sum<n-1)//若sum还不够大则将左端点右移,否则右端点左移
                    l=mid;
                else
                    r=mid;
            }
        }
        cout<<a<<' '<<b<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值