Berry Jam codeforces 1278C

题目大意:

有两种类型的果酱,一个梯子,从中间开始吃,可以吃左边的,也可以吃右边的,最终要使两种类型的果酱的数量想等

题解:

思路对了,但是没考虑完。

对梯子的左侧的果酱I我们用两个数组记录其从1到i的1的数量和从1到i的2的数目,对梯子右侧的果酱保存从i到n的1的数目和2的数目。

然后两种情况,

第一种是最终答案最侧与右侧均有果酱剩余。我们只需要让左侧的1-2等于右侧2-1。

第二种情况,最终答案出现在一侧, 即左侧都吃光或者右侧都吃光。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1E6+7;
const ll INF=1e9+7;
ll arr[N];
ll brr[N];
ll marka1[N];
ll marka2[N];
ll markb1[N];
ll markb2[N];
map<ll,ll >mp;
void solve(){
    mp.clear();
    ll n;
    cin>>n;
    for(ll i=1;i<=n;i++)   cin>>arr[i];
    for(ll i=1;i<=n;i++)   cin>>brr[i];
    for(ll i=1;i<=n;i++){
        if(arr[i]==1) {
            marka1[i]=marka1[i-1]+1;
            marka2[i]=marka2[i-1];
        }
        else {
            marka1[i]=marka1[i-1];
            marka2[i]=marka2[i-1]+1;
        }
    }
    markb1[n+1]=0;
    markb2[n+1]=0;
    for(ll i=n;i>=1;i--){
        if(brr[i]==1){
            markb1[i]=markb1[i+1]+1;
            markb2[i]=markb2[i+1];
        }
        else {
            markb1[i]=markb1[i+1];
            markb2[i]=markb2[i+1]+1;
        }
    }
    for(ll i=n;i>=1;i--){
        ll k=marka1[i]-marka2[i];
        if(mp[k]==0) {
            mp[k]=i;
        }
    }
    ll ans=INF;
    for(ll i=1;i<=n;i++){
        ll k=markb2[i]-markb1[i];
        if(mp[k]!=0){
            ans=min(ans,n-mp[k]+i-1);
        }
    }
    ll ans2=0;
    for(int i=1;i<=n;i++){
        if(marka1[i]==marka2[i]) ans2=i;
    }
    ans2=n-ans2+n;
    ll ans3=n+1;
    for(int i=n;i>=1;i--){
        if(markb1[i]==markb2[i])  ans3=i;
    }
    ans3=n+ans3-1;
    cout<<min(ans3,min(ans,ans2))<<endl;
}
int main(){
    ios::sync_with_stdio(0);
    ll t;
    cin>>t;
    while(t--) solve();
    return 0;
}
原文地址:https://www.cnblogs.com/Accepting/p/12076713.html