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;
}
發佈了54 篇原創文章 · 獲贊 16 · 訪問量 4990
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章