浅谈二分答案

二分答案,就是二分枚举答案,由于进行二分,所以复杂度log(n),比直接
for的时间更短。

【问题描述】

记得上学那会, Fbs同学经常会欺负萝卜同学。有一次,他出了这么一道题目,想为难一下萝卜同学。题目是这样的: 有N个整数X_i, X_i值的范围从0到1000000000。要从中选出C个数( 2<=C<=N),使得任意两个数差的绝对值的最小值尽可能大,求这个最大值。 由于数据太大, 这次萝卜同学的确被难住了,怎么办呢,请你来帮帮萝卜同学吧!
【输入格式】
第一行是N和C。
接下来的N行,每行一个整数。
【输入格式】
一个整数,表示两两最小差距的最大值。
【输入输出样例】
aggr.in aggr.out
5 3
1
2
8
4
9
3
【样例解释】
选择1、 4和8或者选择1、 4和9。
【数据说明】
对于 30%的数据: 2<=N<=100;
对于 60%的数据: 2<=N<=1000;
对于 100%的数据: 2<=N<=100000, 2<=C<=N, 0<=X_i<=1000000000。

这题只要二分枚举绝对值差的最大值,直接暴力枚举这个值,即可求出

#include
using namespace std;
int i,j,k,n,m,tot,ans,l,r,mid,f[100005],use,c,s1;
int read(){
    char c;while(c=getchar(),(c<'0'||c>'9')&&c!='-');
    int x=0,y=1;if(c=='-') y=-1;else x=c-'0';
    while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';
    return x*y;
}
int main()
{
    n=read();c=read();
    for(int i=1;i<=n;i++) f[i]=read();
    sort(f+1,f+1+n);
    l=1,r=1000000000;
    while(l1){
        mid=(l+r)>>1;s1=1;use=1;
        for(int i=2;i<=n;i++){
            if(f[i]-f[s1]>=mid){
                use++;
                s1=i;
            }
        }
        if(use>=c) l=mid;
        else r=mid;
    }
    printf("%d",l);
    return 0;
}

题目描述

有N条绳子,它们的长度分别为Li。如果从它们中切割出K条长度相同的

绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位。

输入输出格式

输入格式:
第一行两个整数N和K,接下来N行,描述了每条绳子的长度Li。

输出格式:
切割后每条绳子的最大长度。

输入输出样例

输入样例#1:
4 11
8.02
7.43
4.57
5.39
输出样例#1:
2.00

这题是二分答案,只不过答案是小数,所以二分的时候要注意精度,注意浮点数误差。
只要枚举小数,算出ans,就可以完成答案。

#include
using namespace std;
int i,j,k,ans,use,n;
double f[100006],l,r,mid;
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>f[i];
    }
    l=(double)1.00,r=(double)100000.00;
    while(l0.0000001){
        mid=(l+r)/2;ans=0;
        for(int i=1;i<=n;i++) 
           ans+=f[i]/mid;
        if(ans>=k) l=(double)mid;
        else r=(double)mid;
    }
    printf("%.2f",l);
    return 0;
}

你可能感兴趣的:(c语言,c++)