zoukankan      html  css  js  c++  java
  • HDU 4430 Yukari's Birthday 【二分查找】

    Yukari's Birthday

    Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5676    Accepted Submission(s): 1370


    Problem Description
    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 ≤ 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 ≤ 1012.
     

    Output
    For each test case, output r and k.
     

    Sample Input
    18 111 1111
     

    Sample Output
    1 17 2 10 3 10
     

    Source


    这个题有个比较坑的地放就是二分太大的时候会爆long long需要控制好上界

    可以用ll high = pow(n, (double)1.0 / r);来紧上界防止爆long long

    也可以在过程中判断long long是否溢出来解决


    第一种做法:

    #include<iostream>    
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<queue>
    #include<map>
    #include<set>
    #include<stack>
    #include<bitset>
    #include<numeric>
    #include<vector>
    #include<string>
    #include<iterator>
    #include<cstring>
    #include<functional>
    #define INF 0x3f3f3f3f
    #define ms(a,b) memset(a,b,sizeof(a))
    using namespace std;
    
    const int maxn = 10010;
    const int mod = 1e9 + 7;
    const double pi = acos(-1.0);
    
    typedef pair<int, int> P;
    typedef long long ll;
    typedef unsigned long long ull;
    
    
    int main()
    {
        ll n;
        while (~scanf("%lld", &n))
        {
            ll ans = n - 1, ans1 = 1, ans2 = n - 1;
            for (int r = 2; r <= 41; r++)
            {
                ll low = 1;
                ll high = pow(n, (double)1.0 / r);
                ll mid;
                while (low <= high)
                {
                    mid = (low + high) >> 1;
                    ll tmp = 1, sum = 0;
                    for (int i = 1; i <= r; i++)
                    {
                        tmp *= mid;
                        sum += tmp;
                    }
                    if (sum == n || sum == (n - 1))
                    {
                        if (mid*r < ans)
                        {
                            ans = mid*r;
                            ans1 = r;
                            ans2 = mid;
                        }
                    }
                    if (sum > n)
                    {
                        high = mid - 1;
                    }
                    else
                    {
                        low = mid + 1;
                    }
                }
            }
            printf("%lld %lld
    ", ans1, ans2);
        }
    }

    第二种做法:


    #include<iostream>    
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<queue>
    #include<map>
    #include<set>
    #include<stack>
    #include<bitset>
    #include<numeric>
    #include<vector>
    #include<string>
    #include<iterator>
    #include<cstring>
    #include<functional>
    #define INF 0x3f3f3f3f
    #define ms(a,b) memset(a,b,sizeof(a))
    using namespace std;
    
    const int maxn = 10010;
    const int mod = 1e9 + 7;
    const double pi = acos(-1.0);
    
    typedef pair<int, int> P;
    typedef long long ll;
    typedef unsigned long long ull;
    
    
    int main()
    {
        ll n;
        while (~scanf("%lld", &n))
        {
            ll ans = n - 1, ans1 = 1, ans2 = n - 1;
            for (int r = 2; r <= 41; r++)
            {
                ll low = 1;
                ll high = n - 1;
                ll mid;
                while (low <= high)
                {
                    mid = (low + high) >> 1;
                    ll tmp = 1, sum = 0;
                    bool flag = 0;
                    for (int i = 1; i <= r; i++)
                    {
                        if (tmp > (n / mid))
                        {
                            flag = 1;
                            break;
                        }
                        tmp *= mid;
                        sum += tmp;
                    }
                    if (!flag&&(sum == n || sum == (n - 1)))
                    {
                        if (mid*r < ans)
                        {
                            ans = mid*r;
                            ans1 = r;
                            ans2 = mid;
                        }
                    }
                    if (flag||sum > n)
                    {
                        high = mid - 1;
                    }
                    else
                    {
                        low = mid + 1;
                    }
                }
            }
            printf("%lld %lld
    ", ans1, ans2);
        }
    }


    Fighting~
  • 相关阅读:
    记一道乘法&加法线段树(模版题)
    2021CCPC网络赛(重赛)题解
    Codeforces Round #747 (Div. 2)题解
    F. Mattress Run 题解
    Codeforces Round #744 (Div. 3) G题题解
    AtCoder Beginner Contest 220部分题(G,H)题解
    Educational Codeforces Round 114 (Rated for Div. 2)题解
    Codeforces Global Round 16题解
    Educational Codeforces Round 113 (Rated for Div. 2)题解
    AtCoder Beginner Contest 182 F
  • 原文地址:https://www.cnblogs.com/Archger/p/12774760.html
Copyright © 2011-2022 走看看