链接: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真是太好用惹!!!