题目描述
给定n个数,从中选出三个数,使得最大的那个减最小的那个的值小于等于d,问有多少种选法。
输入描述:
第一行两个整数n,d(1 <= n <= 100,000,1 <= d <= 1000,000,000); 第二行n个整数满足abs(ai) <= 1,000,000,000。数据保证a单调递增。
输出描述:
输出一个整数表示满足条件的选法。
思路:典型的尺取法,注意是 <= d,这样每一个r, 都要“假设”移动l,算出calc
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn];
int cal(int x)
{
if(x <= 0) return 0;
int sum = 0;
for(int i = x; i >= 1; i--)
sum += i;
return sum;
}
int main()
{
int n, d;
while(~scanf("%d%d",&n, &d))
{
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
int l = 1, r = 2;
long long sum = 0;
while(r <= n)
{
while(l < r && r <= n)
{
if(a[r] - a[l] <= d) sum += cal(r-l-1), r++;
// else if(a[r] - a[l] < d) sum += r - l - 1, r++;
else l++;
}
if(r <= n) r++;
}
printf("%lld\n", sum);
}
return 0;
}