牛客:数对

题目:

牛客:数对_第1张图片

 

解题思路:看到题目的时候,一般第1反应是用两个循环暴力解题,时间复杂度是O(n^2),不能通过,所以要优化,通过找规律。

一、当 y <= k 时, 不可能符合题意,所以 y 从 k+1 开始遍历

(下面二、三是在y固定的情况下讨论)

二、当 x 属于区间 [0, y) 时,有 y-k 个可能的数对

三、可以算出有 n/y 个完整的区间,所以有(n / y) * (y - k) 个可能

四、看剩余区间,如果 n%y < k 则不可能有符合的情况,

                             如果前式大于等于k,有n%y-(k-1)个可能。

五、把所有可能加起来就是y固定时的所有情况,遍历y循环然后加起来就可以了。

        式子:(n / y) * (y - k) +((n%y < k)?0:n%y-(k-1));

详解: 

牛客:数对_第2张图片

k==0时的讨论

 牛客:数对_第3张图片

 

#include 
using namespace std;

int main() {
    long long n = 0, k = 0;
    cin >> n >> k;
    long long count = 0;
    // if(k == 0)
    // {
    //     cout << n*n;
    //     return 0;
    // }
    //k == 0 上面下面两个都可以,上面的更简单
    if(k == 0)
    {
        for(int y = k+1; y <= n; ++y)
        {
        count += (n / y) * (y - k) + ((n % y < k)?0:(n % y) - k);
        }
        cout << count;
        return 0;
    }

    for(int y = k+1; y <= n; ++y)
    {
        count += (n / y) * (y - k) + ((n % y < k)?0:(n % y) - (k - 1));
    }
    cout << count;
    return 0;
}

 

你可能感兴趣的:(算法,数据结构)