zoukankan      html  css  js  c++  java
  • 【积累】想不到可以二分..

    洛谷P2115

    题目描述

    给一组长度为 (N;(3leq Nleq100000)) 的整数数组 (a;(1leq a_ileq 10000)),要求必须删去一个连续区间 ([l,r]) ,且满足 ((2leq lleq rleq n-1)) ,求剩余区间的平均值的最小值。

    输入格式

    (1) 行:一个整数 (N;(3leq Nleq100000))

    (2) 到第 (N+1) 行:第 (i+1) 行包含一个整数 (a_i;(1leq a_ileq 10000))

    输出格式

    (1) 行:一个实数,表示平均值的最小值,四舍五入保留三维小数。

    样例

    输入:

    5
    5
    1
    7
    8
    2
    

    输出:

    2.667
    

    题解

    对于一个满足题意的ans,有:

    [frac{sum-sum[l,r]}{n-(r-l+1)}leq ans\ sum-sum[l,r]leq ans*(n-(r-l+1))\ sum_{i=1}^{l-1}a[i]+sum_{i=r+1}^{n}a[i]leq ans*(n-(r-l+1))\ sum_{1leq i<ligcup r<ileq n}a[i]-ans leq 0\ ]

    所以二分ans,在check函数中判断即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+5;
    const double eps=1e-6;
    
    int a,n;
    double sum[maxn];
    bool eql(double a,double b){return fabs(a-b)<1e-9;}
    bool check(double x)
    {
        double mi=sum[1]-x;
        for(int i=2;i<n;i++)
        {
            if(sum[n]-sum[i]-x*(n-i)+mi<0||eql(sum[n]-sum[i]-x*(n-i)+mi,0))return 1;
            mi=min(mi,sum[i]-x*i);
        }
        return 0;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a),sum[i]=sum[i-1]+a;
        double l=1,r=100000,mid,ans;
        while(l<r||eql(l,r))
        {
            mid=(l+r)/2;
            if(check(mid))ans=mid,r=mid-eps;
            else l=mid+eps;
        }
        printf("%.3lf
    ",ans);
    }
    
  • 相关阅读:
    彻底移除mc
    产生N个不重复的随机数字
    画方格线
    运动方式工具类
    物体围绕另一个物体圆形运动
    检测碰撞工具类(两个类各有特点 可以结合使用)
    hdu 1069 Monkey and Banana (DP)
    hdu 1158 Employment Planning (DP)
    hdu 1003 Max Sum (DP)
    hdu 2550百步穿杨 (DP)
  • 原文地址:https://www.cnblogs.com/kkkek/p/12552262.html
Copyright © 2011-2022 走看看