首页 > 代码库 > HDU - 4430 - Yukari's Birthday

HDU - 4430 - Yukari's Birthday

题目链接:https://vjudge.net/problem/HDU-4430

题目大意:

给出一个n,求出一个r和k,使得首项是k,公比是k的前0~r项和为n,且r*k尽量小。

题目分析:

首先利用等比数列的前n项和公式大概估算出r的大小范围大概最多为45左右。

此时可以枚举r,二分k,求得符合题意的r和k。

注意在二分的过程中可能会溢出,要进行预处理。

注:一开始n开成了int ,WA了一晚上,有毒。

给出代码:

技术分享
#include <cstdio>
#include <iostream>
#include <string>
#include <set>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
long long int n;
long long int find(long long int x)
{
    long long int l=2,r=n,mid,i;
    while(l<=r)
    {
        //cout<<mid<<endl;
        mid=(l+r)/2;
        long long int sum=1;
        long long int ans=0;
        for(i=1; i<=x; i++)
        {
            if(n/sum<mid)
            {
                ans=n+1;
                break;
            }
            sum*=mid;;
            ans+=sum;
            if(ans>n)
                break;
        }
        if(ans==n||ans==n-1)
            return mid;
        else
        {
            if(ans<n-1)
                l=mid+1;
            else
                r=mid-1;
        }
    }
    return -1;

}
int main()
{
    //cin>>n;
    while(cin>>n)
    {
        //long long int minn=n-1;
       /* if(n==1)
        {
            cout<<0<<" "<<1<<endl;
            continue;
        }*/
        long long int r=1,k=n-1,i;
        for(i=2; i<=45; i++)
        {
            long long int t=find(i);
          //  cout<<t<<" "<<i<<endl;
            if(t==-1)
                continue;
            if(t*i<k*r)
            {
             //   minn=t*i;
                r=i;
                k=t;
            }
        }
        cout<<r<<" "<<k<<endl;
    }
    return 0;
}
View Code

 

HDU - 4430 - Yukari's Birthday