zoukankan      html  css  js  c++  java
  • 寻找段落

    题目链接

    其实我本来只是想做道水题QAQ

    首先这个题,找连续子区间最大什么的,很想用单调队列

    回忆一下板子,求连续子区间最大和

    每次从队尾加一个数,如果队列里的和小于0就全弹掉,同时在每次操作后都更新最大值

    本题求平均值最大,类比一下,当队列里的平均值小于某个数就弹掉

    结合一下数据范围可以二分一下标准

    然后因为本题对序列长度有要求

    当长度小于最小要求S时,不操作

    当长度大于最大要求T时,把队首多出来的全弹掉

    当长度大于等于S小于等于T时可以更新答案

    但是要不要弹呢?

    根据单调队列的思想,可以判断多余S的部分的平均值是否大于标准,小于就全弹掉

    这一部分相当于没有长度的要求,可以保证这样做得到的是这部分的最大值

    #include<bits/stdc++.h>
    using namespace std;
    int n,st,ed,line[500000],s[500000],a[500000];
    double eps=1e-5;//这里不要忘了开double
    int read()
    {
    	int x=0,f=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9') 
    	{
    		if(ch=='-') f=-1;//注意输入有负数
     		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    	return f*x;
    }
    int check(double ave)
    {
    	int head=1,tail=0;
    	for(int i=1;i<=n;i++)
    	{
    		line[++tail]=a[i];
    		s[tail]=s[tail-1]+a[i];//前缀和
    		if((tail-head+1>st)&&s[tail-st]-s[head-1]<ave*(tail-st-head+1)) head=tail-st+1;
    		if(tail-head+1>ed) head=tail-ed+1;
    		if(tail-head+1>=st&&tail-head+1<=ed&&(double)(s[tail]-s[head-1])/(double)(tail-head+1)>=ave) return 1;
                    //如上说述
    	}
    	return 0;
    }
    int main()
    {
    	n=read(),st=read(),ed=read();
    	int minn=0x3f3f3f3f,maxn=-0x3f3f3f3f;
    	for(int i=1;i<=n;i++) a[i]=read(),minn=min(minn,a[i]),maxn=max(maxn,a[i]);
    	double l=minn,r=maxn;
    	while(l+eps<r)
    	{
    		double mid=(l+r)/2;
    		if(check(mid)) l=mid;
    		else r=mid;
    	}//long double不能处理负数 
             //作为实数范围内二分的板子吧
    	printf("%.3lf",l);//保留三位小数
    	return 0;
    }
    
  • 相关阅读:
    全新通用编程语言 Def 招募核心贡献者、文档作者、布道师 deflang.org
    全球最快的JS模板引擎:tppl
    4行代码实现js模板引擎
    [Node.js框架] 为什么要开发 Codekart 框架
    Android用BusyBox替换系统toolbox
    纪念一下,昨天换手机了
    在Android上使用gcc编译C/C++源程序
    关于BAPI_ACC_DOCUMENT_POST解读
    关于ABAP和JSON互相转换
    关于客户和供应商预制凭证添加WBS字段
  • 原文地址:https://www.cnblogs.com/qwq-/p/14082059.html
Copyright © 2011-2022 走看看