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