【STL】牛客练习赛16 F.选值 (手写二分应该也能过)

链接:https://www.nowcoder.com/acm/contest/84/F

一开始没好的想法,直接暴力写,然后卡20%

加break剪枝卡65%
然后优化,发现死活过不去了······(水平还是不行啊)

没想到STL中还有这么好用的函数lower_bound

lower_bound      

头文件#include<algorithm>

百度百科

博客

查找有序区间中第一个大于或等于某给定值的元素的位置

函数原型:
template<class ForwardIterator, class Type> ForwardIterator lower_bound( ForwardIterator _First, ForwardIterator _Last, const Type& _Val ); template<class ForwardIterator, class Type, class BinaryPredicate> ForwardIterator lower_bound( ForwardIterator _First, ForwardIterator _Last, const Type& _Val, BinaryPredicate _Comp );

传入参数说明:
_First 要查找区间的起始位置
_Last 要查找区间的结束位置
_Val 给定用来查找的值
_Comp 自定义的表示小于关系的函数对象,根据某个元素是否满足小于关系而返回true或者false

以数组为例
 1 #include<iostream> 
 2 #include<algorithm> 
 3 using namespace std; 
 4 int main() 
 5 { 
 6     int a[4] = { 2, 4, 6, 8 }; //注意此时a中的元素本身就是有序 7     //int * it = lower_bound(a,a+4,3); 
 8     int pos = lower_bound(a, a + 4, 3) - a;//a表示数组的起始位置 
 9     cout <<pos<< endl; 
10     return 0; 
11 } 
AC代码:
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 ll a[100010];
 5 int main()
 6 {
 7     ll n,d,p = 0,i,j;
 8     scanf("%lld %lld",&n,&d);
 9     for(i = 0;i < n;i++)
10         scanf("%lld",&a[i]);
11     for(p = 0,i = n-1;i > 1;i--)
12     {
13         j = lower_bound(a,a+n,a[i]-d)-a;
14         if(j < i-1)
15             p += (i-j)*(i-j-1)/2;   // 等差数列求和公式
16     }
17     printf("%lld\n",p);
18     return 0;
19 }

既然用到了lower_bound,那就再提一下它的“孪生兄弟”upper_bound

返回的是被查序列中第一个大于查找值的指针

博客

代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 int main()
 5 {
 6     ll a[100010];
 7     ll n,d,i,j;
 8     ll p = 0;
 9     scanf("%lld %lld",&n,&d);
10     for(int i = 0;i < n;i++)
11         scanf("%lld",&a[i]);
12     for(i = 0;i < n-1;i++)
13     {
14         j = upper_bound(a,a+n,a[i]+d)-a;
15         j--;
16         p += (j-i-1)*(j-i)/2;
17     }
18     printf("%lld\n",p);
19     return 0;
20 }

STL真是太好用惹!!!



猜你喜欢

转载自www.cnblogs.com/duny31030/p/8966198.html