牛客网 WY49 数对(详解)

前言:内容包括:题目,代码实现,大致思路,代码解读

题目: 

描述

牛牛以前在老师那里得到了一个正整数数对(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)

代码实现: 

#include <stdio.h>
int main() 
{
    long n = 0;
    long k = 0;
    scanf("%ld%ld",&n,&k);
    long y = 0;
    long count = 0;
    if(k == 0)
    {
        printf("%ld",n*n);
    }
    else 
    {
    for(y=k+1;y<=n;y++)
    {
        count+=((n/y)*(y-k))+((n%y<k) ? 0:(n%y-k+1));
    }
    printf("%ld",count);
    }
    return 0;
}

 大致思路:

1. 暴力破解(两个for循环遍历)不可行,采用更优解法

2. 更优解法:

    预备了解:1<= x <= n     1<= y <= n       x%y>=k

    由于x%y的余数要>=k, 故而y最终确定的取值范围是k+1~n

    why:  若y是k,则x%y的余数的的值最大是k-1

a. 将x划分为几个区间:

[1, 2, ..., y]
[y+1, y+2, ..., 2y]
[2
y+1, 2y+2, ..., 3y]
...
[ty+1, ty+2, ..., n]

以下是x的所有取值:1~n    

12……k……y-1y
y+1y+2……k……2y-12y
2y+12y+2……k……3y-13y
3y+13y+2……k……4y-14y
ty+1ty+2……k……n

 x%y的余数: 

12……k……y-10
12……k……y-10
12……k……y-10
12……k……y-10
12……k……n%y

由表可知 

          完整区间(除却最后一个区间)符合题意 余数>=k的值的范围:

                                                      k~y-1

                                                     即y-1-k+1 = y-k

                                                     eg. 区间1~3的个数:3-1+1=3

                                                    故而:只要是完整区间,符合条件的个数是y-k

          最后一个区间 符合题意 余数>=k的值的范围:

                                                       k~n%y

                                                       即n%y-k+1

                                                       故而:最后一个区间符合条件的个数是n%y-k+1

代码解读:

part 1

    if(k == 0)
    {
        printf("%ld",n*n);
    }

k为0,由于任意数对的取模结果都是>=0的,故共有n*n中可能

part 2

    for(y=k+1;y<=n;y++)
    {
        count+=((n/y)*(y-k))+((n%y<k) ? 0:(n%y-k+1));
    }
    printf("%ld",count);

k不为0,y的取值范围是:k+1~n

count:统计符合条件的个数

n/y:表示完整区间的个数

y-k:表示一个完整区间内x%y的余数>=k的个数

n%y:表示最后一段区间的长度,要分情况讨论:

           情况一:最后一段区间的长度<k  

                          这段区间最大的数字%y后的余数是自己,(y的范围是k+1~n)小于k

                          不会出现余数>=k的,即符合条件的个数是0

           情况二:最后一段区间的长度>k

                          这段区间上一定会有%y后的余数>=k符合条件的值

                           个数是n%y-k+1

本期完。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值