zoukankan      html  css  js  c++  java
  • LuoguP2629 好消息,坏消息

    LuoguP2629 好消息,坏消息

    题面

    P2629

    题解

    做法1:

    显然,题目要求求有多少个位置K使得任意N>=i>=K满足sum[i]-sum[k]>=0且任意1<=i<=k-1满足sum[i]+sum[n]-sum[k-1]>=0

    所以当枚举任意一个K的时候,只要记录k~n的前缀和最小值满足及1-k-1的前缀和满足条件即是一组解

    代码如下:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 1000000 + 10;
    
    inline int read()
    {
        int f=1,x=0;
        char ch;
        do
        {
            ch=getchar();
            if(ch=='-') f=-1;
        }while(ch<'0'||ch>'9');
        do
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
    
    int n;
    int a[MAXN];
    int sum[MAXN];
    int prem[MAXN],prem1[MAXN];
    int minn,maxn;
    
    int main()
    {
        memset(prem,127,sizeof(prem));
        memset(prem1,127,sizeof(prem1));
        n=read();minn=1<<30;maxn=-(1<<30);
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=n;i++)
        {
            sum[i]=sum[i-1]+a[i];
            minn=min(minn,sum[i]);
            maxn=max(maxn,sum[i]);
        }
        int res=0;
        for(int i=1;i<=n;i++) prem[i]=min(prem[i-1],sum[i]);
        for(int i=n;i>=1;i--) prem1[i]=min(prem1[i+1],sum[i]);
        for(int k=1;k<=n;k++)
        {    
            int max1=sum[k-1];
            int max2=sum[n]-sum[k-1];
            if(prem1[k]-max1>=0&&max2+prem[k]>=0) res++;
        }
        cout<<res<<endl;
    }

    做法2:

    看一看Luogu题解

    发现可以单调队列搞一搞

    破环为链,把数列扩大一倍

    问题转化为在长度为K的区间中的最小值有没有K-1位置的前缀和大

  • 相关阅读:
    Dynamically allocated memory 动态分配内存【malloc】Memory leaks 内存泄漏
    const pointers
    heap是堆,stack是栈
    Java中使用Cookie
    Postman注册、登录、导出、导入
    HttpServletRequest get post 入参
    判断设置的时间是否大于当前时间
    JS回车登录
    一个普通的Ajax
    Java工具类
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/11151455.html
Copyright © 2011-2022 走看看