二分法(入门)

二分法:      思想其实很早就接触过。


(以下来自360百科)

给定精确度ξ,用二分法求函数f(x)零点近似值的步骤如下:

1 确定区间[a,b],验证f(a)·f(b)<0,给定精确度ξ.

2 求区间(a,b)的中点c.

3 计算f(c).

(1) 若f(c)=0,则c就是函数的零点;

(2) 若f(a)·f(c)<0,则令b=c;

(3) 若f(c)·f(b)<0,则令a=c.

(4) 判断是否达到精确度ξ:即若|a-b|<ξ,则得到零点近似值a(或b),否则重复2-4.








题目描述

给定n个数,从中选出三个数,使得最大的那个减最小的那个的值小于等于d,问有多少种选法。

输入描述:

第一行两个整数n,d(1 <= n <= 100,000,1 <= d <= 1000,000,000);
第二行n个整数满足abs(ai) <= 1,000,000,000。数据保证a单调递增。

输出描述:

输出一个整数表示满足条件的选法。


链接:https://www.nowcoder.com/acm/contest/84/F
来源:牛客网

示例1

输入

4 3
1 2 3 4

输出

4
示例2

输入

4 2
-3 -2 -1 0

输出

2
示例3

输入

5 19
1 10 20 30 50

输出

1



ac:


#include<iostream>
#include<cstdio>
#define ll long long
ll a[100010];
int main()
{
    int i,n;
ll d,res,mid,temp;
while (scanf ("%d%lld",&n,&d)!=EOF)
{
res=temp=0;
for (i=1;i<=n;i++)
scanf ("%lld",&a[i]);
for (i=1;i<=n;i++)
{
ll l=i,r=n;temp=0;
while (l<=r)
{
mid =(l+r)>>1;
if (a[mid]-a[i]<=d)
{
temp=mid;
l=mid+1;
}
else 
r=mid-1;
}
if (temp!=0&&temp>(i+1))
res=res+(temp-i-1)*(temp-i)/2;
}
printf ("%lld\n",res);
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/a1204675546/article/details/80184131