牛客2019校招真题在线编程---数对

时间限制:1秒 空间限制:32768K 

题目描述

牛牛以前在老师那里得到了一个正整数数对(x, y), 牛牛忘记他们具体是多少了。

但是牛牛记得老师告诉过他x和y均不大于n, 并且x除以y的余数大于等于k。

牛牛希望你能帮他计算一共有多少个可能的数对。

输入描述:

输入包括两个正整数n,k(1 <= n <= 10^5, 0 <= k <= n - 1)。

输出描述:

对于每个测试用例, 输出一个正整数表示可能的数对数量。

示例1

输入

复制

5 2

输出

复制

7

说明

满足条件的数对有(2,3),(2,4),(2,5),(3,4),(3,5),(4,5),(5,3)

 思路:当k==0时,所有数对均符合,即n*n

我们要求满足条件的数对,也就是求满足条件的数,等价于求符合条件的余数的个数,因此,先打一个余数表格看看,                                                                       列为y ,  行为x,值为x%y

x    \     y  1 2 3 4 5 6 7 8
1 0 1 1 1 1 1 1 1
2 0 0 2 2 2 2 2 2
3 0 1 0 3 3 3 3 3
4 0 0 1 0 4 4 4 4
5 0 1 2 1 0 5 5 5
6 0 0 0 2 1 0 6 6
7 0 1 1 3 2 1 0 7
8 0 0 2 0 3 2 1 0

我们可以清楚的观察出,每一列都有一个循环,其循环大小就是当前对应y的值,其值的循环是1,2,3...y-1,0。

那么求值就变成了求每一列循环次数*每个循环中符合要求余数个数 + 当前列不完整循环中符合要求余数个数

也就是对于每一列要找的大于等于k的余数,就变成了求如下几个值:

1.当前列循环次数    n/y,

2.当前列符合要求的余数。观察一下就能很清楚的看出来,对每一个循环而言,大于等于k的数为 y-k,而循环次数为y/n   ,所以余数个数为     (y-k)*(y/n)

3.不完整循环中的余数。  如y==3时,循环为120,最后一个循环为12,不完整,因此这里对最后一个循环做特判。

首先,最后一个循环的余数个数为n%y, 设 m+n%y == y,则补成完整循环之后为完整循环余数为 m + n%y - k == y - k,可是,若按照完整循环计算,会多出m-1个符合要求的余数,剪去,得  m + n%y - k - (m-1) == y - k - (m-1) , 右边即为符合要求余数个数,

最后化简为   n%y + 1 - k == 符合要求余数个数。 

代码如下:

#include
#include
using namespace std;
typedef long long ll;
int main()
{
    ll n, k;
    cin>>n>>k;
    if(k==0)
    {
        cout<

 

你可能感兴趣的:(思维,牛客网)