zoukankan      html  css  js  c++  java
  • Berry Jam

    C. Berry Jam
    Karlsson has recently discovered a huge stock of berry jam jars in the basement of the house. More specifically, there were 2n jars of strawberry and blueberry jam.

    All the 2n jars are arranged in a row. The stairs to the basement are exactly in the middle of that row. So when Karlsson enters the basement, he sees exactly n jars to his left and n jars to his right.

    Being the starightforward man he is, he immediately starts eating the jam. In one minute he chooses to empty either the first non-empty jar to his left or the first non-empty jar to his right.

    Finally, Karlsson decided that at the end the amount of full strawberry and blueberry jam jars should become the same.

    For example, this might be the result:

    He has eaten 1 jar to his left and then 5 jars to his right. There remained exactly 3 full jars of both strawberry and blueberry jam.
    Jars are numbered from 1 to 2n from left to right, so Karlsson initially stands between jars n and n+1.

    What is the minimum number of jars Karlsson is required to empty so that an equal number of full strawberry and blueberry jam jars is left?

    Your program should answer t independent test cases.

    Input
    The first line contains one integer (t (1≤t≤1000)) — the number of test cases.

    The first line of each test case contains a single integer (n (1≤n≤10^5)).

    The second line of each test case contains 2n integers (a_1,a_2,…,a_{2n} (1≤a_i≤2))(a_i=1) means that the i-th jar from the left is a strawberry jam jar and (a_i=2) means that it is a blueberry jam jar.

    It is guaranteed that the sum of n over all test cases does not exceed (10^5)

    Output
    For each test case print the answer to it — the minimum number of jars Karlsson is required to empty so that an equal number of full strawberry and blueberry jam jars is left.
    input

    4
    6
    1 1 1 2 2 1 2 1 2 1 1 2
    2
    1 2 1 2
    3
    1 1 1 1 1 1
    2
    2 1 1 1
    

    output

    6
    0
    6
    2
    

    题意: 给定2n长度数组, 从中间开始删除, 求删除长度的最小值使得两种果酱数目一样.
    把2换成-1,即求最小长度使得前缀和为0.
    设s[i]为前缀和, 固定区间左端点i, 即求合法位置的一个最左边的右端点j 使得 s[j]-s[i-1]==s[2n]
    显然,j合法的位置是([n,2n]), 用pos[v]数组记录n右边最靠近n的v的位置.
    ans=0特判
    前缀和范围是([-2n,2n]),整体加上2n
    不可能的v值直接continue

    #include<bits/stdc++.h>
    using namespace std;
    char buf[1<<20],*_=buf,*__=buf;
    #define gc() (_==__&&(__=(_=buf)+fread(buf,1,1<<20,stdin),_==__)?EOF:*_++)
    #define TT template<class T>inline
    TT bool read(T &x){
        x=0;char c=gc();bool f=0;
        while(c<48||c>57){if(c==EOF)return 0;f^=(c=='-'),c=gc();}
        while(47<c&&c<58)x=(x<<3)+(x<<1)+(c^48),c=gc();
        if(f)x=-x;return 1;
    }
    const int MAXN=1e5+8;
    int s[MAXN],pos[MAXN<<2];
    int main() {
        int t,n,nn;read(t);
        while(t--){
            read(n);nn=n<<1;
            memset(pos,-1,sizeof(pos));
            for(int i=1,x;i<=nn;++i){
                read(x);
                s[i]=s[i-1]-2*x+3;
            }
            for(int i=n<<1;i>=n;--i)pos[s[i]+nn]=i;
            int d=s[nn],ans=nn;
            if(d!=0)for(int i=n+1;i;--i){
                if(d+s[i-1]+nn<0||d+s[i-1]>nn)continue;//不可能的值
                int j=pos[d+s[i-1]+nn];
                if(n-i+1>ans)break;//不可能有更小的ans了
                if(i<=j)ans=min(ans,j-i+1);
            }
            else ans=0;//特判
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    jax + php 写入数据库最简单实例
    JavaScript--水平幻灯片
    深入理解CSS3 gradient斜向线性渐变
    js基础-1
    html5 Canvas 如何自适应屏幕大小
    清除浮动塌陷
    spring MVC配置
    dom4j使用
    Visio绘制时序图
    Eclipse中引来的jar包乱码
  • 原文地址:https://www.cnblogs.com/foursmonth/p/14161895.html
Copyright © 2011-2022 走看看