noip模拟赛 整除

分析:最暴力的思想就是枚举一边啦,然后就会发现有很多n/i的结果都是相同的,可以每次跳过这一段,这样能过60分.

      想不出其它解法了,打个表找了一下规律:

               ans   num

                1     1

                2     2

                3     2

                4     3

                5     3

会发现除了第一个ans以外,其它的就是一个等差数列,应用一下等差数列求和公式,二分一下项数就可以了.

 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;

ll n, ans;

ll cal(ll x)
{
    return 2 * x + x * (x - 1) / 2; 
}

int main()
{
    scanf("%lld", &n);
    ll l = 0, r = 1000000000;
    while (l <= r)
    {
        ll mid = (l + r) >> 1;
        if (cal(mid) * 2 + 1 <= n)
        {
            ans = mid;
            l = mid + 1;
        }
        else
            r = mid - 1;
    }
    if (cal(ans) * 2 + 1 == n)
        printf("%lld\n", ans * 2 + 1);
    else
    {
        ll temp = ans + 2, temp2 = n - (cal(ans) * 2 + 1);
        if (temp >= temp2)
            printf("%lld\n", ans * 2 + 2);
        else
            printf("%lld\n", ans * 2 + 3);
    }

    return 0;
}

 

 

 

                                              

posted @ 2017-10-19 21:48  zbtrs  阅读(187)  评论(0编辑  收藏  举报