农夫约翰的 奶牛棒球(寒假每日一题 13)_i++ 头奶牛排成一排,每头奶牛都位于数轴中的不同位置上。

它们正在练习投掷棒球。

农夫约翰观看时,观察到一组三头牛 奶牛棒球(寒假每日一题 13)_算法_02 完成了两次成功的投掷。

奶牛棒球(寒假每日一题 13)_#include_03 把球扔给她右边的牛 奶牛棒球(寒假每日一题 13)_i++_04,然后牛 奶牛棒球(寒假每日一题 13)_i++_04 把球扔给她右边的牛 奶牛棒球(寒假每日一题 13)_双指针_06

约翰指出,第二次投掷的距离不少于第一次投掷的距离,也不超过第一次投掷的距离的两倍。

请计算共有多少组牛 奶牛棒球(寒假每日一题 13)_算法_02 可能是约翰所看到的。

输入格式
第一行包含整数 奶牛棒球(寒假每日一题 13)_i++

接下来 奶牛棒球(寒假每日一题 13)_i++ 行,每行描述一头牛的位置。

输出格式
输出奶牛三元组 奶牛棒球(寒假每日一题 13)_算法_02 的数量。

奶牛棒球(寒假每日一题 13)_算法_02 需满足,奶牛棒球(寒假每日一题 13)_i++_04奶牛棒球(寒假每日一题 13)_#include_03 的右边,奶牛棒球(寒假每日一题 13)_双指针_06奶牛棒球(寒假每日一题 13)_i++_04 的右边,并且从 奶牛棒球(寒假每日一题 13)_i++_04奶牛棒球(寒假每日一题 13)_双指针_06 的距离在 奶牛棒球(寒假每日一题 13)_算法_18 之间,其中 XY 表示从 奶牛棒球(寒假每日一题 13)_#include_03奶牛棒球(寒假每日一题 13)_i++_04 的距离。

数据范围
奶牛棒球(寒假每日一题 13)_二分_21
奶牛所在的位置坐标范围 奶牛棒球(寒假每日一题 13)_双指针_22

输入样例:

5
3
1
10
7
4

输出样例:

4

样例解释
四个可能的奶牛三元组为: 奶牛棒球(寒假每日一题 13)_双指针_23


解题思路

  1. 排序(升序排列)
  2. 枚举奶牛棒球(寒假每日一题 13)_双指针_24
  3. 然后根据双指针特性(单调性)奶牛棒球(寒假每日一题 13)_双指针_25二分 找奶牛棒球(寒假每日一题 13)_#include_26的范围
  4. 找第一个满足奶牛棒球(寒假每日一题 13)_算法_27的数,找第一个满足奶牛棒球(寒假每日一题 13)_双指针_28的数奶牛棒球(寒假每日一题 13)_双指针_29
  5. 奶牛棒球(寒假每日一题 13)_#include_26的取值就是奶牛棒球(寒假每日一题 13)_二分_31

​双指针 49ms​

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010;

int p[N];

int main(){

int n, res = 0;

cin >> n;

for(int i = 0; i < n; i++) cin >> p[i];

sort(p, p + n);

for(int i = 0; i + 2 < n; i++){
for(int j = i + 1, l = j + 1, r = j + 1; j + 1 < n; j++){

while(l < n && p[l] - p[j] < p[j] - p[i]) l++;
while(r < n && p[r] - p[j] <= 2 * (p[j] - p[i])) r++;
res += (r - l);
}
}

cout << res << endl;
return 0;
}

​二分 742ms​

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010;

int p[N];

int main(){

int n, res = 0;

cin >> n;

for(int i = 0; i < n; i++) cin >> p[i];

sort(p, p + n);

for(int i = 0; i + 2 < n; i++){
for(int j = i + 1; j + 1 < n; j++){

int l = lower_bound(p, p + n, 2 * p[j] - p[i]) - p;
int r = upper_bound(p, p + n, 3 * p[j] - 2 * p[i]) - p;

res += (r - l);
}
}

cout << res << endl;
return 0;
}