牛客:数对

题目:

 

解题思路:看到题目的时候,一般第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));

详解: 

k==0时的讨论

 

 

#include <iostream>
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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值