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;
    }
    
  • 相关阅读:
    windows cmd 中获取当前时间并输出此时间
    使用windows批处理来让git每日自动更新代码
    拒绝垃圾文章 在 ejabberd 中使用 MySQL
    IOS调试lldb命令常用,po,
    IOS 多语言本地化 完美解决方案
    [转]Xcode封装.Bundle文件
    百度地图SDK引用问题 Symbol(s) not found for architecture armv64
    loaded the "ViewController" nib but the view outlet was not set. 处理方式
    initWithFrame 和 initWithCoder
    使用IB_DESIGNABLE与IBInspectable特性实现可在视图编辑器的功能栏中设置
  • 原文地址:https://www.cnblogs.com/foursmonth/p/14161895.html
Copyright © 2011-2022 走看看