Lower Bound-STL
题目网址
https://www.hackerrank.com/challenges/cpp-lower-bound/problem
Sample Input
8
1 1 2 2 6 9 9 15
4
1
4
9
15
Sample Output
Yes 1
No 5
Yes 6
Yes 8
题目的大意为:
第一行输出一个数字为n;第二行输出n个数字,第三行输出一个数字y,下面有y个数字,让你查询在上面的数字中是否存在这些数字,如果存在输出"YES"并且输出这个数字,否则输出“NO”,输出大于它的最小数字。
lower_bound,upper_bound的头文件
#include “algorithm”;
lower_bound:
功能:查找非递减序列[first,last) 内第一个大于或等于某个元素的位置。
返回值:如果找到返回找到元素的地址否则返回last的地址。(这样不注意的话会越界,小心)
用法:int t=lower_bound(a+l,a+r,key)-a;(a是数组)。
upper_bound:
功能:查找非递减序列[first,last) 内第一个大于某个元素的位置。
返回值:如果找到返回找到元素的地址否则返回last的地址。(同样这样不注意的话会越界,小心)
用法:int t=upper_bound(a+l,a+r,key)-a;(a是数组)。
#include<bits/stdc++.h>
using namespace std;
#define maxx 2e+5
int main()
{
vector<int>v;
vector<int>::iterator low,up;
int n,m,i,t,j;
cin>>n;
string a,b;
a="Yes";
b="No";
for(i=1;i<=n;i++)
{
cin>>t;
v.push_back(t);
}
cin>>m;
while(m--)
{
int k;
cin>>k;
low=lower_bound(v.begin(),v.end(),k);
up=upper_bound(v.begin(),v.end(),k);
if(up-low!=0)
{
cout<<a<<" ";
cout<<(low-v.begin())+1<<endl;
}
else
{
cout<<b<<" ";
cout<<(low-v.begin())+1<<endl;
}
}
}
写这道题,主要是为了这二个函数;
lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的。
在从小到大的排序数组
lower_bound(begin,end,num):
从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):
从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
在从大到小的排序数组中,重载lower_bound()和upper_bound()
lower_bound(begin,end,num,greater()):
从数组的begin位置到end-1位置二分查找第一个小于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound(begin,end,num,greater()):
从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
例如:
在数组组中的下标
0 1 2 3 4
1 2 2 2 4
我们要查找 2 我们用upper_bound找到数字在数组中的下标为 1 ,我们又通过low_bound找到数字在数组中的下标为 4,得到的数组下标相减结果为3,所给数中刚好存在3个2。