zoukankan      html  css  js  c++  java
  • [BZOJ 2017.11月 月赛] 组题

    题目传送-BZOJ5090

    题意:

    给出n个数。求连续区间(长度大于等于k)最大平均值。
    (n le 100000)

    题解:

    二分答案,用double
    O(n)check:先把原数组都减去二分的答案,判断有没有一段长度大于等于K的区间的元素和大于等于0就行了

    过程:

    由于BZOJ评测机过慢。。二分最大二分次数T了不知道多少发。。

    代码:

    inline db sgn(db x) {return x<-eps ? -1 : x>eps;}
    const int N=100010;
    int a[N];
    db b[N];
    int n,k;
    int l,r;
    inline bool judge(db x) {
    	for(int i=1;i<=n;i++) b[i]=1.0*a[i]-x;
    	db sum=0,pre=0,mi=0; l=1; r=k;
    	for(int i=1;i<=k;i++) sum+=b[i]; if(sgn(sum)>=0) return true;
    	for(int i=k+1;i<=n;i++) {
    		sum+=b[i]; sum-=b[i-k];
    	// if(x==1.25) printf("%lf
    ",sum);
    		pre+=b[i-k];
    		if(pre<mi) {mi=pre; l=i-k+1;}
    		if(sum+pre-mi>=0) {r=i; return true;}
    	}
    	return false;
    }
    signed main()
    {
    	read(n); read(k);
    	for(int i=1;i<=n;i++) read(a[i]);
    	db L=-1e8,R=1e8;
    	db ret=0;
    	int T=100;
    	while(T--) {
    		// printf("%lf %lf
    ",L,R);
    		db mid=(L+R)*0.5;
    		if(judge(mid)) {ret=mid; L=mid;}
    		else R=mid;
    	}
    	// assert(judge(1.25));
    	assert(judge(ret));
    	ll fz=0,fm=0;
    	for(int i=l;i<=r;i++) fz+=a[i];
    	fm=r-l+1;
    	bool fl=0;
    	if(fz<0) fl=1,fz=-fz;
    	ll g=__gcd(fz,fm);
    	// printf("%lld %lld %d %d
    ",fz,fm,l,r);
    	if(fl) putchar('-');
    	printf("%lld/%lld
    ",fz/g,fm/g);
    	
    	return 0;
    }
    

    用时:1h

  • 相关阅读:
    数据对象映射模式
    策略模式
    适配模式
    注册模式
    单例模式
    工厂模式
    PHP魔法方法的使用
    【转】通过 ulimit 改善系统性能
    HDMI相关知识
    中国三种3G网络频段
  • 原文地址:https://www.cnblogs.com/functionendless/p/9442300.html
Copyright © 2011-2022 走看看