zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 21 D

    传送门

    题意

    将n个数划分为两块,最多改变一个数的位置,
    问能否使两块和相等

    分析

    因为我们最多只能移动一个数x,那么要么将该数往前移动,要么往后移动,一开始处理不需要移动的情况
    那么遍历sum[i]
    如果往前移动,sum[k]+(sum[i]-sum[i-1])=sum[n]/2,k∈[1,i-1]
    如果往后移动,sum[k]-(sum[i]-sum[i-1])=sum[n]/2,k∈[i+1,n]
    一开始我没有考虑往后移动
    时间复杂度(O(nlog(n)))

    trick

    代码

    #include<cstdio>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    int n;
    ll sum[100100];
    ll ans,x;
    
    bool find(int l,int r,ll val)
    {
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(val<sum[mid]) r=mid-1;
            if(val>sum[mid]) l=mid+1;
            if(val==sum[mid]) return 1;
        }
        return 0;
    }
    int flag=0;
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%lld",&x);
            sum[i]=sum[i-1]+x;
        }
        if(sum[n]&1) { puts("NO");return 0; }
        ans=sum[n]/2;
        //if(find(1,n,ans)) {flag=1;goto loop;}
        for(int i=1;i<=n;++i)
        {
            ll ret=sum[i]-sum[i-1]+ans;
            if(find(i+1,n,ret)) { flag=1;break; }
            ret=ans-(sum[i]-sum[i-1]);
            if(find(1,i-1,ret)) { flag=1;break; }
        }
        //if(find(1,n-2,sum[n-1]-ans)) flag=1;
        loop:
        flag?puts("YES"):puts("NO");
    }
    
  • 相关阅读:
    GDUFE ACM-1087
    背包九讲
    OJ4TH|Inverse number:Reborn
    OJ4TH|Let's play a game
    GG第四次作业
    OpenCV(3)其他常用数据类型
    OpenCV学习(2)读取视频和摄像头
    OpenCV(1)读写图像
    GG第三次作业
    GG第二次作业
  • 原文地址:https://www.cnblogs.com/chendl111/p/6863966.html
Copyright © 2011-2022 走看看