题解 | #万万没想到之抓捕孔连顺#

万万没想到之抓捕孔连顺

http://www.nowcoder.com/questionTerminal/c0803540c94848baac03096745b55b9b

解法1——二分查找

用二分查找寻找以l为开头时,可行的最后一个r。

那么[l,r]区间的方案数为1+2+...+(r-l-1)。

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), d = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) a[i] = in.nextInt();
        final long MOD = 99997867;
        int l = 2, r = n - 1;
        long ans = 0;
        for (int i = 0; i < n - 2; ++i) {
            while (l < r) {
                int mid = l + r + 1 >> 1;
                if (a[mid] - a[i] > d) r = mid - 1;
                else l = mid;
            }
            long x = r - i - 1, s = x * (x + 1) / 2;
            ans = (ans + s) % MOD;
            r = n - 1;
        }
        System.out.println(ans);
    }
}

解法2——双指针

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), d = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) a[i] = in.nextInt();
        Arrays.sort(a);
        final long MOD = 99997867;
        long ans = 0;
        for (int l = 0, r = 0; l < n - 2; ++l) {
            while (r < n - 1 && a[r + 1] <= a[l] + d) r++;
            int x = Math.max(0, r - l - 1);
            long s = (long)x * (x + 1) / 2;
            ans = (ans + s) % MOD;
        }
        System.out.println(ans);
    }
}
全部评论

相关推荐

10-13 17:47
门头沟学院 Java
wulala.god:图一那个善我面过,老板网上找的题库面的
点赞 评论 收藏
分享
11-01 08:48
门头沟学院 C++
伤心的候选人在吵架:佬你不要的,能不能拿户口本证明过户给我。。球球了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务