C. Berry Jam(前缀和)

C. Berry Jam(前缀和)

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output

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.

For example, the basement might look like this:
在这里插入图片描述
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≤105).

The second line of each test case contains 2n integers a1,a2,…,a2n (1≤ai≤2) — ai=1 means that the i-th jar from the left is a strawberry jam jar and ai=2 means that it is a blueberry jam jar.

It is guaranteed that the sum of n over all test cases does not exceed 105.

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.

Example
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

outpu

6
0
6
2

Note
The picture from the statement describes the first test case.

In the second test case the number of strawberry and blueberry jam jars is already equal.

In the third test case Karlsson is required to eat all 6 jars so that there remain 0 jars of both jams.

In the fourth test case Karlsson can empty either the second and the third jars or the third and the fourth one. The both scenarios will leave 1 jar of both jams.

题意

从中间梯子位置向左或向右一直吃果酱,知道剩下的两种果酱的数量一样多结束,问你最少吃几瓶果酱可以满足条件;

解题思路

像这类问题我们可以先转换成0-1数列,然后求其前缀和,和后缀和,如果前缀和等于后缀和那么表示刚好平衡,如果不等那说明两者的数量和还不同,我们可以用一个map来记录前一半数的前缀和等于某个值时出现的位置,后缀和用前缀和相减就可以了。然后从中间向后遍历,遍历的值减去最后前缀和的值,然后看看map里面有这个值不,如果有计算一下需要吃几个,每次取最小的结果就可以了;
举个例子吧, (这里把,2看成0,有个2就减1)
n=6;
然后12个数据是 1 1 1 2 2 1 2 1 2 1 1 2
前缀和各项值是:1 2 3 2 1 2 1 2 1 2 3 2
然后map里面记录的分别是 1== 5, 2== 6,3==3;
我们用sum[i]-sum[n*2],是因为前缀合计算的是 1比2多了几个,我们这样减了一下刚好是2比1多了几个。如果前面刚好有1比2多的数量等于后面从i这个位置2比1多的数量,那么把中间的这部分吃了就刚好。我们这样顺序遍历下最后取最小值就可以了。

代码

#include <bits/stdc++.h>
using namespace std;
int a[200009];//记录前缀和 
int main()
{
    int t,n;
    cin>>t;
    while(t--) {
        cin>>n;
        map<int ,int>mp;
        mp[0]=0;//第一个位置一定要设置,为了解决刚好满足情况,不用吃一瓶。 
        for (int i = 1,x; i <= n * 2; i++) {
            cin>>x;
            if(x==2) x=-1;
            a[i]=a[i-1]+x;
            if(i<=n) mp[a[i]]=i;//记录 前缀和为 a【i】 时是第几个位置 
        }
        int ans=n*2;//记录最少需要几次 
        for (int i = n; i <= n * 2; i++) {
            auto it=mp.find(a[i]-a[n*2]);//在前面的前缀和里面寻找有没有后面2比1多相同数量的值 
            if(it!=mp.end()) ans=min(ans,i-it->second);//如何存在就更新ans的值 
        }
        cout<<ans<<"\n";
    }
    return 0;
}
发布了49 篇原创文章 · 获赞 14 · 访问量 4348

猜你喜欢

转载自blog.csdn.net/qq_43750980/article/details/103630685