C. Berry Jam
Posted pixel-teee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C. Berry Jam相关的知识,希望对你有一定的参考价值。
题意:给出一排果酱,从之间开始往左右两边吃,使得剩下的红蓝果酱的数量一样,并且吃的最少?
分析:对于这种贡献题目,我们可以将果酱的贡献换成01序列或者1-1序列,这题需要换成1-1序列,意味着如果sum[i] == q,那么从1 ~ i这个果酱序列里,蓝果酱和红果酱之间的数量差值为q,
那么我们可以从中间开始计算,先记录sum[1]~sum[n]之间的位置,那么sum[i]表示左边剩余的两种果酱的差值,sum[2n] - sum[i]表示右边剩余的两种果酱的差值,那么,我们只需要这个前缀和和后缀和是相反数,那么剩余的果酱数量就相同了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 5;
int sum[2 * N];
int main()
{
int t;
scanf("%d", &t);
int n;
while (t--)
{
map<int, int> pos;
//从中间开始往左右两边吃
scanf("%d", &n);
int d;
pos[0] = 0;
for (int i = 1; i <= 2 * n; ++i)
{
scanf("%d", &d);
if (d == 2)
{
d = -1;
}
else
{
d = 1;
}
sum[i] = sum[i - 1] + d;
if (i <= n) pos[sum[i]] = i;//i == n,意味着左边的都不吃
//计算的时候,让sum[n] - sum[i]就是左边吃的
}
int ans = n * 2;
//枚举右边的
for (int i = n; i <= n * 2; ++i)
{
int q = sum[i] - sum[n * 2];
auto it = pos.find(q);
if (it != pos.end()) ans = min(ans, i - it->second);
}
cout << ans << endl;
}
return 0;
}
以上是关于C. Berry Jam的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 78 (Rated for Div. 2) C. Berry Jam
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段