纯纯的规律题。
考虑差分。不难发现每次操作相当于交换相邻两个元素,同时不能出现相邻的 0 0 0,那么将 0 0 0作为特征元素,如果初始 0 0 0的数目相等那么移动一下就好了,否则不难想到可以对 a 2 a_2 a2, a n a_n an单独取反,使得 a 2 ∼ n a_{2\sim n} a2∼n中 0 0 0的数目与之匹配,不难想到只有最多 O ( n ) O(n) O(n)种情况,暴力即可做到 O ( n 2 ) O(n^2) O(n2)。
#include<bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
using namespace std;
int n,a[5005],b[5005];
int tot1,tot2,res(inf);
char s[5005],t[5005];
deque<int>v1,v2;
int solve(int l,int r){
deque<int>v3(v1);int tot(abs(l)+abs(r));
if((a[1]^(abs(l)&1))!=b[1])return inf;
if(l>0)for(int i=0;i<l;i++)v3.push_front(2);
if(r>0)for(int i=0;i<r;i++)v3.pb(n);
if(l<0){
for(int i=0;i<abs(l);i++)tot+=v3[i]-2;
v3.erase(v3.begin(),v3.begin()+abs(l));
}
if(r<0){
for(int i=0;i<abs(r);i++)tot+=n-v3[v3.size()-i-1];
v3.erase(v3.end()-abs(r),v3.end());
}assert(v2.size()==v3.size());
for(int i=0;i<v3.size();i++){
tot+=abs(v3[i]-v2[i]);
}return tot;
}
signed main(){
scanf("%d%s%s",&n,s+1,t+1);
s[0]=t[0]=0;
for(int i=1;i<=n;i++){
s[i]-='0',t[i]-='0';
a[i]=s[i]^s[i-1],b[i]=t[i]^t[i-1];
}
for(int i=2;i<=n;i++){
if(a[i]==0)v1.pb(i);
if(b[i]==0)v2.pb(i);
}
for(int i=-n;i<=n;i++){
res=min(res,solve(i,v2.size()-v1.size()-i));
}cout<<res;
}