二分函数的使用方法及实战练习

使用方法解释: 
在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

提交0.46K

 

通过0.34K

 

时间限制1000MS

 

内存限制125MB
题目描述

虽然 Miss Medusa 到了北京,领了科技创新奖,但是他还是觉得不满意。原因是:他发现很多人都和他一样获了科技创新奖,特别是其中的某些人,还获得了另一个奖项——特殊贡献奖。而越多的人获得了两个奖项,Miss Medusa就会越眼红。于是她决定统计有哪些人获得了两个奖项,来知道自己有多眼红。

输入格式

第一行两个整数 n,m,表示有 n 个人获得科技创新奖,m 个人获得特殊贡献奖。

第二行 n 个正整数,表示获得科技创新奖的人的编号。

第三行 m 个正整数,表示获得特殊贡献奖的人的编号。

输出格式

输出一行,为获得两个奖项的人的编号,按在科技创新奖获奖名单中的先后次序输出。

输入样例#1
4 3 
2 15 6 8 
8 9 2 
输出样例#1
2 8
题目说明

对于 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;
}

【P11050】 砍树
提交0.72K

 

通过0.54K

 

时间限制1000MS

 

内存限制64MB
题目描述

伐木工人米尔科需要砍倒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个整数,表示砍树的最高高度。

输入样例#1
5 20  
4 42 40 26 46 
输出样例#1
36
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;
}

【P10844】 勇者斗恶龙
提交0.72K

 

通过0.4K

 

时间限制1000MS

 

内存限制64MB
题目描述

你的王国里有一条n个头的恶龙,你希望雇一些骑士把它杀死(即砍掉所有头)。村里有m个骑士可以雇佣,一个能力值为x的骑士可以砍掉恶龙一个直径不超过x的头,且需要支付x个金币。如何雇佣骑士才能砍掉恶龙的所有头,且需要支付的金币最少?注意,一个骑士只能砍一个头(且不能被雇佣两次)。

输入格式

输入包含多组数据。每组数据的第一行为正整数n和m(1≤n,m≤20 000);以下n行每行为一个整数,即恶龙每个头的直径;以下m行每行为一个整数,即每个骑士的能力。输入结束标志为n=m=0。

输出格式

对于每组数据,输出最少花费。如果无解,输出“Loowater is doomed!”。

输入样例#1
2 3 





2 1 


10 
0 0 
输出样例#1
11 
Loowater is doomed! 
c++代码
#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;
}

【P11074】 不相交的区间
提交0.53K

 

通过0.42K

 

时间限制1000MS

 

内存限制64MB
题目描述

数轴上有n个开区间(ai,bi ),选择尽量多个区间,使得这些区间两两没有公共点。

image.png

输入格式

第一行 ,输入一个整数n(n<=100000),表示有n个开区间。

第二行到第n+1行,输入两个整数a、b,(0<=a<b<=100000),表示区间的开始和结束。

输出格式

输出一个整数表示能够取得最多不相交的区间。

输入样例#1

1 2 
4 6 
5 9 
1 5 
4 9 
1 7
输出样例#1
2
#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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值