使用方法解释:
在b数组用二分法 lower_bound(a+1,a+1+n,v);返回位置 a+1~a+1+n 中v的位置 若没有,则返回它应该所在的位置 ,若多个则返回第一个的位置
int a[5]={1,1,3,6,7,12};
cout<<lower_bound(a,a+5,100)-a;//6 若没有,则返回它应该所在的位置
cout<<lower_bound(a,a+5,12)-a; //5 返回位置 a+1~a+1+n 中v的位置
cout<<lower_bound(a,a+5,1)-a;// 0 若多个则返回第一个的位置
在b数组用二分法 upper_bound(a+1,a+1+n,v);返回位置 a+1~a+1+n 中v的位置加1 若没有,则返回它应该所在的位置 ,若多个则返回最后一个的位置加1;
int a[5]={1,1,3,6,7,12};
cout<<upper_bound(a,a+5,100)-a;//6 若没有,则返回它应该所在的位置
cout<<upper_bound(a,a+5,12)-a; //5 返回位置 a+1~a+1+n 中v+1的位置
cout<<upper_bound(a,a+5,1)-a; //1 若多个则返回最后一个的位置加1
**************使用这两种函数的前提是 数组是有序的(加上sort) -(数组名)=位置(数组下标)
例题:
【P10818】 眼红的Medusa
虽然 Miss Medusa 到了北京,领了科技创新奖,但是他还是觉得不满意。原因是:他发现很多人都和他一样获了科技创新奖,特别是其中的某些人,还获得了另一个奖项——特殊贡献奖。而越多的人获得了两个奖项,Miss Medusa就会越眼红。于是她决定统计有哪些人获得了两个奖项,来知道自己有多眼红。
第一行两个整数 n,m,表示有 n 个人获得科技创新奖,m 个人获得特殊贡献奖。
第二行 n 个正整数,表示获得科技创新奖的人的编号。
第三行 m 个正整数,表示获得特殊贡献奖的人的编号。
输出一行,为获得两个奖项的人的编号,按在科技创新奖获奖名单中的先后次序输出。
2 15 6 8
8 9 2
对于 60% 的数据,1≤n,m≤1000,获得奖项的人的编号<2×109;
对于 100% 的数据,1≤n,m≤105,获得奖项的人的编号<2×109。
数据保证第二行任意两个数不同,第三行任意两个数不同。
c++代码
#include<bits/stdc++.h>
using namespace std;
int a[100010],b[100010],n,m;
int main() {
cin>>n>>m;
for(int i=1; i<=n; i++) {
cin>>a[i];
}
for(int i=1; i<=m; i++) {
cin>>b[i];
}
sort(b+1,b+1+m);
for(int i=1; i<=n; i++) {
if(upper_bound(b+1,b+1+m,a[i])-lower_bound(b+1,b+1+m,a[i])>0) {
cout<<a[i]<<" ";
}
}
return 0;
}
伐木工人米尔科需要砍倒M米长的木材。这是一个对米尔科来说很容易的工作,因为他有一个漂亮的新伐木机,可以像野火一样砍倒森林。不过,米尔科只被允许砍倒单行树木。
米尔科的伐木机工作过程如下:米尔科设置一个高度参数H(米),伐木机升起一个巨大的锯片到高度H,并锯掉所有的树比H高的部分(当然,树木不高于H米的部分保持不变)。米尔科就行到树木被锯下的部分。
例如,如果一行树的高度分别为20,15,10和17,米尔科把锯片升到15米的高度,切割后树木剩下的高度将是15,15,10和15,而米尔科将从第1棵树得到5米,从第4棵树得到2米,共得到7米木材。
米尔科非常关注生态保护,所以他不会砍掉过多的木材。这正是他为什么尽可能高地设定伐木机锯片的原因。帮助米尔科找到伐木机锯片的最大的整数高度H,使得他能得到木材至少为M米。换句话说,如果再升高1米,则他将得不到M米木材。
第1行:2个整数N和M,N表示树木的数量(1<=N<=1000000),M表示需要的木材总长度(1<=M<=2000000000)
第2行:N个整数表示每棵树的高度,值均不超过1000000000。所有木材长度之和大于M,因此必有解。2.代码输出格式
第1行:1个整数,表示砍树的最高高度。
4 42 40 26 46
c++代码
#include<bits/stdc++.h>
using namespace std;
long long a[1000010],n,m;
bool check(long long mid){
long long sum=0;
for(int i=1;i<=n;i++){
if(a[i]>mid)sum+=a[i]-mid;
}
return sum>=m;
}
int main() {
cin>>n>>m;
long long mx=0;
for(int i=1;i<=n;i++){
cin>>a[i];
mx=max(mx,a[i]);
}
int l=0,r=mx,mid,ans;
while(l<=r){
mid=(l+r)/2;
if(check(mid)){
ans=mid;
l=mid+1;
}else r=mid-1;
}
cout<<ans;
return 0;
}
你的王国里有一条n个头的恶龙,你希望雇一些骑士把它杀死(即砍掉所有头)。村里有m个骑士可以雇佣,一个能力值为x的骑士可以砍掉恶龙一个直径不超过x的头,且需要支付x个金币。如何雇佣骑士才能砍掉恶龙的所有头,且需要支付的金币最少?注意,一个骑士只能砍一个头(且不能被雇佣两次)。
输入包含多组数据。每组数据的第一行为正整数n和m(1≤n,m≤20 000);以下n行每行为一个整数,即恶龙每个头的直径;以下m行每行为一个整数,即每个骑士的能力。输入结束标志为n=m=0。
对于每组数据,输出最少花费。如果无解,输出“Loowater is doomed!”。
5
4
7
8
4
2 1
5
5
10
0 0
Loowater is doomed!
#include<bits/stdc++.h>
using namespace std;
int n,m,a[20010],b[20010],ans;
int main() {
while(cin>>n>>m) {
if(n==0&&m==0)break;
ans=0;
for(int i=1; i<=n; i++)
cin>>a[i];
for(int i=1; i<=m; i++)
cin>>b[i];
sort(a+1,a+1+n);
sort(b+1,b+1+m);
int j=1;
for(int i=1; i<=m; i++) {
if(b[i]>=a[j]) {
ans+=b[i];
j++;
if(j>n)break;
}
}
if(j>n)cout<<ans<<endl;
else cout<<"Loowater is doomed!"<<endl;
}
return 0;
}
数轴上有n个开区间(ai,bi ),选择尽量多个区间,使得这些区间两两没有公共点。
第一行 ,输入一个整数n(n<=100000),表示有n个开区间。
第二行到第n+1行,输入两个整数a、b,(0<=a<b<=100000),表示区间的开始和结束。
输出一个整数表示能够取得最多不相交的区间。
1 2
4 6
5 9
1 5
4 9
1 7
#include<bits/stdc++.h>
using namespace std;
struct area{
int b,e;
}a[100010];
bool cmp(area x,area y){
return x.e<y.e;
}
int main() {
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].b>>a[i].e;
}
sort(a+1,a+1+n,cmp);
int cnt=1,end=a[1].e;
for(int i=2;i<=n;i++){
if(a[i].b>=end){
cnt++;
end=a[i].e;
}
}
cout<<cnt;
return 0;
}