题解:CF251A Points on Line

题面

Points on Line

题面翻译

题目描述

Petya 很喜欢点。最近,他的妈妈给了他 n n n 个位于 O X OX OX(实数轴)上的点。现在 Petya 想知道有多少种不同的方法可以在数轴上选择 3 3 3 个不同点,使 3 3 3 个点中距离最远的两个点的距离不超过 d d d

注意: 3 3 3 个点的排列顺序是无关紧要的(意思就是说, 3 3 3 个点是相同的,交换顺序也只算 1 1 1 种)。

输入输出格式

输入格式:

第一行有两个数: n ( 1 ≤ n ≤ 1 0 5 ) n\left ( 1 \le n \le 10^5 \right ) n(1n105) d ( 1 ≤ d ≤ 1 0 9 ) d\left ( 1 \le d \le 10^9 \right ) d(1d109)。下面一行包含n个整数 x 1 , x 2 , x 3 , x 4 , … x n x_1,x_2,x_3,x_4, \dots x_n x1,x2,x3,x4,xn(绝对值小于等于 1 0 9 10^9 109),表示妈妈给 Petya 的点的坐标。

保证坐标按绝对升序输入。

输出格式:

输出一个整数————选出三个数,使最远的两个数之间的距离不超过d,的方法数。

在C++中,请不要用 %lld 来读入64位的整数。推荐使用 cincout%l64d 来读入。

说明

在样例一中,任何挑选方式都是可行的。

在样例二中只有 − 3 , − 2 , − 1 {-3, -2, -1} 3,2,1 − 2 , − 1 , 0 {-2, -1, 0} 2,1,0 是可行的。

在第三个样例中只有 1 , 10 , 20 {1, 10, 20} 1,10,20 是可行的。

题目描述

Little Petya likes points a lot. Recently his mom has presented him n n n points lying on the line O X OX OX . Now Petya is wondering in how many ways he can choose three distinct points so that the distance between the two farthest of them doesn’t exceed d d d .

Note that the order of the points inside the group of three chosen points doesn’t matter.

输入格式

The first line contains two integers: n n n and d d d ( 1 < = n < = 1 0 5 , 1 < = d < = 1 0 9 1<=n<=10^{5}, 1<=d<=10^{9} 1<=n<=105,1<=d<=109 ). The next line contains n n n integers x 1 , x 2 , . . . , x n x_{1},x_{2},...,x_{n} x1,x2,...,xn , their absolute value doesn’t exceed 1 0 9 10^{9} 109 — the x x x -coordinates of the points that Petya has got.

It is guaranteed that the coordinates of the points in the input strictly increase.

输出格式

Print a single integer — the number of groups of three points, where the distance between two farthest points doesn’t exceed d d d .

Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

样例 #1

样例输入 #1
4 3
1 2 3 4
样例输出 #1
4

样例 #2

样例输入 #2
4 2
-3 -2 -1 0
样例输出 #2
2

样例 #3

样例输入 #3
5 19
1 10 20 30 50
样例输出 #3
1

提示

In the first sample any group of three points meets our conditions.

In the seconds sample only 2 groups of three points meet our conditions: − 3 , − 2 , − 1 {-3, -2, -1} 3,2,1 and − 2 , − 1 , 0 {-2, -1, 0} 2,1,0.

In the third sample only one group does: 1 , 10 , 20 {1, 10, 20} 1,10,20.

题解

思路

1.暴力 O ( n 3 ) O\left ( n^{3} \right ) O(n3)

暴力枚举 3 3 3 个数,符合要求就将答案加 1 1 1

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,d,a[100005],ans=0;
signed main(){
	cin.tie(0),cout.tie(0);
	cin>>n>>d;
	for(int i=1;i<=n;i++)	cin>>a[i];
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
			for(int k=j+1;k<=n;k++)
				if(a[k]-a[i]<=d)
					ans++;
	
	cout<<ans<<"\n";
	return 0;
}

恭喜!TLE

2.正解 O ( n log ⁡ n ) O \left ( n\log_{}{n} \right ) O(nlogn)

  • 枚举最小的数。
  • 二分找出最大的合法的数。
  • 排列组合求出答案。

设最小的数的位置为 l l l,最大的数的位置为 r r r。所以 r = (upper_bound( a + l, a + 1 + n, a[l] + d) - a - 1),因此当前的的合法选择有 C r − l 2 C_{r-l}^{2} Crl2 种方案。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,d,a[100005],ans=0;
int C(int x){//组合数
	return (x*(x-1))/2;
}
signed main(){
	cin.tie(0),cout.tie(0);
	cin>>n>>d;
	for(int i=1;i<=n;i++)	cin>>a[i];
	for(int i=1;i<=n;i++){
		int r=(upper_bound(a+i,a+1+n,a[i]+d)-a-1);
		ans+=C(r-i);
	}
	cout<<ans<<"\n";
	return 0;
}

AC 记录

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值