网易2018---数对
数对
时间限制:1秒
空间限制:32768K
牛牛以前在老师那里得到了一个正整数数对(x, y), 牛牛忘记他们具体是多少了。
但是牛牛记得老师告诉过他x和y均不大于n, 并且x除以y的余数大于等于k。
牛牛希望你能帮他计算一共有多少个可能的数对。
输入描述:
输入包括两个正整数n,k(1 <= n <= 10^5, 0 <= k <= n - 1)。
输出描述:
对于每个测试用例, 输出一个正整数表示可能的数对数量。
输入例子1:
5 2
输出例子1:
7
例子说明1:
满足条件的数对有(2,3),(2,4),(2,5),(3,4),(3,5),(4,5),(5,3)
法一(借鉴):数学办法,看题解能看懂,但是不知道怎么想到这个数学办法的。时间复杂度是o(n)。唉。。。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class Main { 2 3 public static void main(String[] args) throws IOException { 4 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 5 String line = in.readLine(); 6 String[] s = line.split(" "); 7 int n = Integer.parseInt(s[0]), k = Integer.parseInt(s[1]); 8 long cnt = 0l; 9 //k=0的情况特殊处理,因为所有%都会大于0 10 if(k == 0) { 11 cnt = (long)n * (long)n; 12 System.out.println(cnt); 13 return; 14 } 15 //将y从k+1枚举到n 16 //对于每一个y,余数范围是0,1,2。。。y-1,而其中余数满足范围的是>=k的部分 17 //又x在n的范围内,满足n范围内%y>=k的情况有(n / y) * (y - k)种,还要考虑n%y>=k的情况。 18 for(int y = k + 1; y <= n; y++) { 19 cnt += (n / y) * (y - k); 20 if(n % y >= k) { 21 cnt += n % y - k + 1; 22 } 23 } 24 System.out.println(cnt); 25 } 26 27 }
例子:n=6,k=2时,满足条件的数对如下:(按y=k+1到n,枚举,可以从中找到上面代码的规律。但是好难啊)
y=3时,(2, 3) (5, 3)
y=4时,(2, 4) (3, 4) (6, 4)
y=5时,(2, 5) (3, 5) (4, 5)
y=5时,(2, 6) (3, 6) (4, 6) (5, 6)
法二:当然自己想出来的是o(n^2)的解决办法,毫无疑问的超时了。关键是只过了10%。伤心。然后我又添加了k=0的特殊情况的处理,过了30%。代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 2 String line = in.readLine(); 3 String[] s = line.split(" "); 4 int n = Integer.parseInt(s[0]), k = Integer.parseInt(s[1]); 5 long cnt = 0l; 6 if(k == 0) { 7 cnt = (long)n * (long)n; 8 System.out.println(cnt); 9 return; 10 } 11 for(int i = n; i >= k; i--) { 12 for(int j = 2; j <= n; j++) { 13 if(i % j >= k) { 14 cnt++; 15 } 16 } 17 } 18 System.out.println(cnt);