二分--- 1>.最小值最大化--- 2>.最大值最小化

1>.最小值最大化

洛谷 :P2678-跳石头

这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终 点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达 终点。

为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳 跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能 移走起点和终点的岩石)。

输入输出格式

输入格式:

输入文件名为 stone.in。

输入文件第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终 点之间的岩石数,以及组委会至多移走的岩石数。

接下来 N 行,每行一个整数,第 i 行的整数 Di(0 < Di < L)表示第 i 块岩石与 起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同 一个位置。

输出格式:

输出文件名为 stone.out。 输出文件只包含一个整数,即最短跳跃距离的最大值。

输入输出样例

输入样例#1:  复制
25 5 2 
2
11
14
17 
21
输出样例#1:  复制
4

说明

输入输出样例 1 说明:将与起点距离为 2 和 14 的两个岩石移走后,最短的跳跃距离为 4(从与起点距离 17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点)。

另:对于 20%的数据,0 ≤ M ≤ N ≤ 10。 对于50%的数据,0 ≤ M ≤ N ≤ 100。

对于 100%的数据,0 ≤ M ≤ N ≤ 50,000,1 ≤ L ≤ 1,000,000,000。

题解 :去掉M个石头,那么就剩下n-m个石头,我们就可以对n进行二分,判断条件是 给一个mid值,判断其作为             最大值可不可以将n个石头分成(n-m)块,可以,l(左指针)=mid ; 否则 r(右指针)=mid,依次二分,直到不             能分为止。
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
int n,m;
ll k,l=0,r=0;
ll a[50005];

bool fun(ll mid){
int ans=1;
ll p=a[0];
for(int i=1;i<m;i++){
if(a[i]-p>=mid){
p=a[i];
ans++;
}
}
return ans<(m-k);
}
int main(){
scanf("%lld %d %d",&n,&m,&k);
a[0]=0;
if(k==m){
printf("%d\n",n);                                  // 注意:第三个样例,等把m个全部丢掉是,应该是 n (只有起点和终点)。
return 0;
}
for(int i=1;i<=m;i++){
scanf("%lld",&a[i]);
}
a[m+1]=n;
m=m+2;

l=0,r=a[m-1];
while(r-1>l){
ll mid=(r+l)>>1;
if(fun(mid)){
r=mid;
}
else{
l=mid;
}
}
printf("%lld\n",l);
return 0;
}


Aggressive cows
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 18567   Accepted: 8825

Description

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,...,xN (0 <= xi <= 1,000,000,000). 

His C (2 <= C <= N) cows don't like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input

* Line 1: Two space-separated integers: N and C 

* Lines 2..N+1: Line i+1 contains an integer stall location, xi

Output

* Line 1: One integer: the largest minimum distance

Sample Input

5 3
1
2
8
4
9

Sample Output

3

Hint

OUTPUT DETAILS: 

FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3. 

Huge input data,scanf is recommended.

同理 : 最小值最大化

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[100005];
ll n,c,l=0,r=0;

int fun(ll mid){
ll ans=1;
ll p=a[0];
for(int i=1;i<n;i++){
if(a[i]-p>=mid){
p=a[i];
ans++;
}
}
return ans<c;
}
int main(){
scanf("%lld %lld",&n,&c);
for(int i=0;i<n;i++){
scanf("%lld",&a[i]);
}
sort(a,a+n);
// for(int i=0;i<n;i++){
// l=min(l,a[i]);
// r+=(a[i]);
// }
    l=0,r=a[n-1];
while(r-l>1){
ll mid=(r+l)>>1;
if(fun(mid))
r=mid;
else
l=mid;
}
printf("%lld\n",l);
return 0;
}


2>.最大值最小化

链接:https://www.nowcoder.com/acm/contest/106/K
来源:牛客网

题目描述 
It’s universally acknowledged that there’re innumerable trees in the campus of HUST.

Now you're going to walk through a large forest. There is a path consisting of N stones winding its way to the other side of the forest. Between every two stones there is a distance. Let di indicates the distance between the stone i and i+1.Initially you stand at the first stone, and your target is the N-th stone. You must stand in a stone all the time, and you can stride over arbitrary number of stones in one step. If you stepped from the stone i to the stone j, you stride a span of (di+di+1+...+dj-1). But there is a limitation. You're so tired that you want to walk through the forest in no more than K steps. And to walk more comfortably, you have to minimize the distance of largest step.
输入描述:
The first line contains two integer N and K as described above.
Then the next line N-1 positive integer followed, indicating the distance between two adjacent stone.
输出描述:
An integer, the minimum distance of the largest step.
示例1
输入

6 3
1 3 2 2 5
输出

5

题意 :给你n个石头,,编号1~n,再给你一个最多行走步数 K,再给你 n-1个数,              代表两个石头之间的距离,问你在不超过K步的情况下,你一步最小的距                  离?

题解 :同样二分

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll M;
ll n,k,a[100050],b[100050];
int fun(ll mid){
    int l=0,r=1,sum=0;
    while(r<n){
        while(r<n&&b[r]-b[l]<=mid){
            r++;
        }
        sum++;
        l=r-1;
    }
    return sum<=k;
}
 
int main(){
    ll l=0,r;
    scanf("%lld %lld",&n,&k);
    for(ll i=1;i<n;i++){
        scanf("%lld",&a[i]);
        M+=a[i];
        l=max(l,a[i]);
    }
    r=M;
    b[0]=0;
    for(ll i=1;i<n;i++){
        b[i]=b[i-1]+a[i];
    }
    while(r-l>1){
        ll mid=(r+l)>>1;
        if(fun(mid)){
            r=mid;
        }
        else
         l=mid;
    }
    printf("%lld\n",fun(l)?l:r);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/black_horse2018/article/details/80148368