Berry Jam(前缀和+二分)

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

All the 2n2n 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 nn jars to his left and nn 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 11 jar to his left and then 55 jars to his right. There remained exactly 33 full jars of both strawberry and blueberry jam.
Jars are numbered from 11 to 2n2n from left to right, so Karlsson initially stands between jars nn and n+1n+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 tt independent test cases.

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

The first line of each test case contains a single integer nn (1≤n≤1051≤n≤105).

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

It is guaranteed that the sum of nn over all test cases does not exceed 105105.

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
Output
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 66 jars so that there remain 00 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 11 jar of both jams.
思路:我们把左边和右边的1,2前缀都求出来,并且求出每个位置1和2的差值。对左边的差值进行排序,差值相等位置靠前的在前面。我们遍历右边的差值,二分找出左边应该的有的差值。不断的取最小值。
代码如下:

#include<bits/stdc++.h>
#define ll long long
#define inf 1e9
using namespace std;

const int maxx=1e5+100;
struct node{
	int pos;
	int num;
	bool operator<(const node &a)const{
		if(num!=a.num) return num<a.num;
		else return pos<a.pos;
	}
}p[maxx];
int a[maxx<<1],b[maxx],sum[10];
int lsum1[maxx],lsum2[maxx],rsum1[maxx],rsum2[maxx];
int n;

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		memset(sum,0,sizeof(sum));
		for(int i=1;i<=2*n;i++) scanf("%d",&a[i]),sum[a[i]]++;
		lsum1[0]=lsum2[0]=rsum1[0]=rsum2[0]=0;
		for(int i=n;i>=1;i--)
		{
			lsum1[n-i+1]=lsum1[n-i]+(a[i]==1);
			lsum2[n-i+1]=lsum2[n-i]+(a[i]==2);
		}
		for(int i=n+1;i<=2*n;i++)
		{
			rsum1[i-n]=rsum1[i-n-1]+(a[i]==1);
			rsum2[i-n]=rsum2[i-n-1]+(a[i]==2);
		}
		for(int i=1;i<=n;i++)
		{
			p[i].num=lsum1[i]-lsum2[i];
			p[i].pos=i;
		}
		sort(p+1,p+1+n);
		for(int i=1;i<=n;i++) b[i]=p[i].num;
		int czt=sum[1]-sum[2],cnt;
		if(czt==0)
		{
			cout<<0<<endl;
			continue;
		}
		int _max=inf;
		int pos=lower_bound(b+1,b+1+n,czt)-b;//不需要右边就可以补全差值。
		if(b[pos]==czt&&pos<=n) _max=p[pos].pos;//由于是多组输入,要保证pos的位置不比n大,这个地方一定要注意,否则会出错。
		for(int i=1;i<=n;i++)
		{
			cnt=rsum1[i]-rsum2[i];
			cnt=czt-cnt;//在左边应该找的差值。
			if(cnt==0) _max=min(_max,i);
			else
			{
				int pos1=lower_bound(b+1,b+1+n,cnt)-b;
				if(b[pos1]==cnt&&pos1<=n) _max=min(_max,i+p[pos1].pos);//!!!!
			}
		}
		cout<<_max<<endl;
	}
	return 0;
}

就因为多组输入,然后卡了一下午!!
努力加油a啊,(o)/~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

starlet_kiss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值