AcWing 1945. 奶牛棒球

AcWing 1945. 奶牛棒球

题目描述
农夫约翰的 N 头奶牛排成一排,每头奶牛都位于数轴中的不同位置上。
它们正在练习投掷棒球。
农夫约翰观看时,观察到一组三头牛 (X,Y,Z) 完成了两次成功的投掷。
牛 X 把球扔给她右边的牛 Y,然后牛 Y 把球扔给她右边的牛 Z。
约翰指出,第二次投掷的距离不少于第一次投掷的距离,也不超过第一次投掷的距离的两倍。
请计算共有多少组牛 (X,Y,Z) 可能是约翰所看到的。

输入格式
第一行包含整数 N。
接下来 N 行,每行描述一头牛的位置。

输出格式
输出奶牛三元组 (X,Y,Z) 的数量。
(X,Y,Z) 需满足,Y 在 X 的右边,Z 在 Y 的右边,并且从 Y 到 Z 的距离在 [XY,2XY] 之间,其中 XY 表示从 X 到 Y 的距离。

数据范围
3≤N≤1000,
奶牛所在的位置坐标范围 [0,108]。

输入样例:

5
3
1
10
7
4

输出样例:

4

样例解释
四个可能的奶牛三元组为:1−3−7,1−4−7,4−7−10,1−4−10。

解题思路
将奶牛排序后,遍历牛 X、Y 的所有可能,
根据条件 Y 到 Z 的距离在 [XY,2XY] 之间查找得到牛 Z 的端点,相减得到 Z 的可能数量

安利两个函数(利用二分查找)

lower_bound(begin,end,num)//返回begin到end-1范围内第一个大于或等于num的数字的地址,未找到返回end
upper_bound(begin,end,num)//返回begin到end-1范围内第一个大于num的数字的地址,未找到返回end
//返回的地址减去起始地址begin,得到找到数字在数组中的下标。

代码

#include<iostream>
#include<algorithm>
using namespace std;
int arr[1000];
int main() {
	int n;
	cin >> n;
	int sum = 0;
	for (int i = 0; i < n; ++i) {
		cin >> arr[i];
	}
	sort(arr, arr + n);
	for (int i = 0; i < n; ++i) {
		for (int j = i+1; j < n; ++j) {
			int tmp = arr[j] - arr[i];
			int a = lower_bound(arr + j + 1, arr + n, arr[j] + tmp) - arr;
			if (a != n) {
				int b = upper_bound(arr + j + 1, arr + n, arr[j] + tmp * 2) - arr;
				sum += (b - a);
			}
		}
	}
	cout << sum;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值