zoukankan      html  css  js  c++  java
  • 浅谈二分答案

    二分答案,就是二分枚举答案,由于进行二分,所以复杂度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<bits/stdc++.h>
    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(l<r-1){
            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<bits/stdc++.h>
    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(l<r-0.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;
    }
  • 相关阅读:
    学算法的那些年,吴师兄接触的网站、软件、视频、书籍大揭秘
    阮一峰:CSS Modules 用法教程
    截取url参数
    在dotnet core实现类似crontab的定时任务
    开源一个基于dotnet standard的轻量级的ORM框架-Light.Data
    ABP Vnext使用mysql数据库
    实现ElementUI Dialog宽度响应式变化
    使用Vue Baidu Map对百度地图实现输入框搜索定位
    使用Docker搭建HttpRunnerManager环境
    SpringBoot集成spring aop开发
  • 原文地址:https://www.cnblogs.com/stevensonson/p/7612204.html
Copyright © 2011-2022 走看看