二分查找1
题目描述
给定一个n,再给定n个数,从小到大排列,给定一个x,说出小于等于x的最大的数。
输入描述
输入两行,第一行两个数分别是n,x。(1 <= n <= 1000000)
第二行有n个数。
输出描述
输出一个数,即答案。
#include<iostream>
#include<iomanip>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std;
int main(){
int n,x;
int a[1000005];
cin>>n>>x;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int l=1,r=n;
while(l<r){
int mid=(l+r+1)>>1;
if(a[mid]>x){
r=mid-1;
}
else if(a[mid]<=x){
l=mid;
}
}
cout<<a[l];
return 0;
}
二分查找2
题目描述
给定一个n,再给定n个数,从小到大排列,给定一个x,说出大于等于x的最小的数。
输入描述
输入两行,第一行两个数分别是n,x。
(1 <= n <= 1000000)
第二行有n个数。
输出描述
输出一个数,即答案。
#include<iostream>
#include<iomanip>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std;
int a[1000005];
int main(){
int n,x;
cin>>n>>x;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int l=1,r=n;
while(l<r){
int mid=(l+r)>>1;
if(a[mid]>= x){
r=mid;
}
else if(a[mid]<x){
l=mid+1;
}
}
cout<<a[l];
return 0;
}
砍伐树木
题目描述
小华被小林叫去砍树,他需要砍倒m米长的木材。现在,小华弄到了一个奇怪的伐木机。伐木机工作过程如下:小华设置一个高度参数h(米),伐木机升起一个巨大的锯片到高度h,并锯掉所有的树比h高的部分(当然,树木不高于h米的部分保持不变)。小华就得到树木被锯下的部分。
例如,如果一行树的高度分别为20、15、10、17米,小华把锯片升到15米的高度,切割后树木剩下的高度将是15、15、10、15米,而小华将从第一棵树得到5米,从第4棵树得到2米,共得到7米木材
小华非常关注生态保护,所以他不会砍掉过多的木材。这正是他为什么要尽可能高的设定伐木机锯片的原因。帮助小华找到伐木机锯片的最大的整数高度h,使得他能得到的木材至少为m米。换句话说,如果再升高1米,则他将得不到m米木材
输入描述
第一行两个整数n和m,n表示树木的数量,m表示需要的木材总长度
第二行n个整数,表示每棵树的高度,值均不超过10^9.保证所有木材长度之和大于m,因此必然有解
输出描述
一行一个整数,表示砍树的最高高度
#include<iostream>
#include<iomanip>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std;
long long n,m,maxx;
long long a[1000005];
long long ck(long long mid){
long long sum=0;
for(int i=1;i<=n;i++){
if(a[i]>=mid){
sum+=a[i]-mid;
}
}
return sum;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
maxx=max(maxx,a[i]);
}
long long l=0,r=maxx;
while (l<r){
long long mid=(l+r+1)>>1;
if(ck(mid)>=m){
l=mid;
}
else{
r=mid-1;
}
}
cout<<l;
return 0;
}
月度开销
题目描述
农夫约翰是一个精明的会计师。他意识到自己可能没有足够的钱来维持农场的运转了。
他计算出并记录下了接下来 N (1 ≤ N ≤ 100,000) 天里每天需要的开销。
约翰打算为连续的M (1 ≤ M ≤ N) 个财政周期创建预算案,他把一个财政周期命名为fajo月。
每个fajo月包含一天或连续的多天,每天被恰好包含在一个fajo月里。
约翰的目标是合理安排每个fajo月包含的天数,使得开销最多的fajo月的开销尽可能少。
输入描述
第一行包含两个整数N,M,用单个空格隔开。
接下来N行,每行包含一个1到10000之间的整数,按顺序给出接下来N天里每天的开销。
输出描述
一个整数,即最大月度开销的最小值。
#include<iostream>
#include<iomanip>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std;
int n,m,a[100005],maxx,sum=0;
int ck(long long mid){
int cnt=1;
int pos=mid;
for(int i=1;i<=n;i++){
if(mid>=a[i]){
mid=mid-a[i];
}
else{
cnt++;
mid=pos;
mid=mid-a[i];
}
}
return cnt;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
maxx=max(maxx,a[i]);
sum+=a[i];
}
long long l=maxx,r=sum;
while(l<r){
long long mid=(l+r)>>1;
if(ck(mid)>m){
l=mid+1;
}
else{
r=mid;
}
}
cout<<l;
return 0;
}
好斗的奶牛
题目描述
农夫约翰搭了一间有N个牛舍的小屋,牛舍排在一条线上,第i号牛舍在xi的位置。但是有M头牛对小屋很不满意。因此经常互相攻击。约翰为了防止牛之间相互伤害,因此决定把每头牛都放在离其他牛舍尽可能远的牛舍。
输入描述
第一行输入n(n<=1000)和m(m<=n)
接下来的n行有N个数,第i行为对应的xi
输出描述
输出距离最近的两头奶牛间的距离的最大值。
#include<iostream>
#include<iomanip>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std;
int a[1000005];
int n,m;
int c(int mid){
int cnt=1,pos=a[1];
for(int i=2;i<=n;i++){
if(a[i]-pos>=mid){
cnt++;
pos=a[i];
}
}
return cnt;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
int l=1,r=a[n]-a[1];
while(l<r){
int mid=(l+r+1)>>1;
if(c(mid)>= m){
l=mid;
}
else if(c(mid)<m){
r=mid-1;
}
}
cout<<l;
return 0;
}