题解 | #Average#

Course

https://ac.nowcoder.com/acm/contest/11255/A

题目描述:
简单来说就是给你两个数组,a和数组b。然后定义矩阵w[i][j]=a[i]+b[i],在这个矩阵内找一个子矩阵得到,这个字矩阵内的平均值最大,这个子矩阵长不得小于x,宽不得小于y。
题目分析:
每个矩阵的平均值为:
图片说明
又由于w[i][j]=a[i]+b[j]得子矩阵的和就等于
图片说明
平均值就为
图片说明
这样就可以吧题目分为分别找第一项的最大值与第二项的最大值的和,由于题目给的大小为1e5我们可以用二分来找最大值。

bool check(ll x,ll*v,int tx,int t)
{
    for(int i=1;i<=t;i++){
        ans[i]=v[i]+ans[i-1]-x;
    }
    ll mini=0;
    for(int i=tx;i<=t;i++){
        if(ans[i]-mini>=0)return 1;
        mini=min(mini,ans[i-tx+1]);
    }    
    return 0;
}
ll f(ll *v,int tx,int t)//二分答案
{
    ll l=0,r=1e9;
    for(int i=1;i<=1000;i++){
        ll mid=(l+r)/2;
        if(check(mid,v,tx,t))l=mid;
        else r=mid;
    }
    return l;
}

AC代码

#include<bits/stdc++.h>
#define ll double 
using namespace std;
const int N=1e5+20;
ll a[N],b[N],ans[N]={0};
bool check(ll x,ll*v,ll tx);
ll f(ll *v,int tx,int t);
int main()
{
    int n,m,x,y,i;
    cin>>n>>m>>x>>y;
    for(i=1;i<=n;i++)cin>>a[i];
    for(i=1;i<=m;i++)cin>>b[i];
    printf("%.10lf\n",f(a,x,n)+f(b,y,m));
    return 0;
}
bool check(ll x,ll*v,int tx,int t)
{
    for(int i=1;i<=t;i++){
        ans[i]=v[i]+ans[i-1]-x;
    }
    ll mini=0;
    for(int i=tx;i<=t;i++){
        if(ans[i]-mini>=0)return 1;
        mini=min(mini,ans[i-tx+1]);
    }    
    return 0;
}
ll f(ll *v,int tx,int t)
{
    ll l=0,r=1e9;
    for(int i=1;i<=1000;i++){
        ll mid=(l+r)/2;
        if(check(mid,v,tx,t))l=mid;
        else r=mid;
    }
    return l;
}
全部评论

相关推荐

找工作勤劳小蜜蜂:自我描述部分太差,完全看不出想从事什么行业什么岗位,也看不出想在哪个地区发展,这样 会让HR很犹豫,从而把你简历否决掉。现在企业都很注重员工稳定性和专注性,特别对于热爱本行业的员工。 你实习的工作又太传统的it开发(老旧),这部分公司已经趋于被淘汰,新兴的互联网服务业,比如物流,电商,新传媒,游戏开发和传统的It开发有天然区别。不是说传统It开发不行,而是就业岗位太少,基本趋于饱和,很多老骨头还能坚持,不需要新血液。 工作区域(比如长三角,珠三角,成渝)等也是HR考虑的因素之一,也是要你有个坚定的决心。否则去几天,人跑了,HR会被用人单位骂死。
点赞 评论 收藏
分享
评论
6
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务