CF1237H
WitheredZeal · · 题解
题意
有一个长度为
你需要构造一种方案使得这个序列变成目标序列,或者声明无解。
题解
好像有正经的做法,这里给一个靠谱的随机化乱搞。
首先考虑,由于翻转的前缀都是偶数,那么相当于把
将
显然如果
考虑这样一个构造过程:
从后往前扫,每次把最后一位确定了,然后将剩下的部分变成子问题。
比如说我们现在在对
首先我们需要找到一个
这样我们用了
但是这样有一个问题:现在要搞个
我们选择一个
这样还是有个问题,这样我们用
我们运用人类智慧,每次在合法的数中随机选取一个,基本上是不是能保证不存在
在加上还有
看了一下评测记录,用的最多次数的一个点也只有 2915 次,看上去非常靠谱。
代码
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
#define pii pair<int,int>
#define fi first
#define se second
#define rd(x) x=read()
#define wt(x) write(x)
using namespace std;
const int N=4000+5;
const int M=1e5+5;
const int mod=998244353;
int read(){int x=0;char ch=getchar();while(ch>'9'||ch<'0'){ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x;}
void write(int x){if(x<0){putchar('-');x=-x;}if(x>=10)write(x/10);putchar(x%10+'0');}
int n,m,k;
char s[N],t[N];
int a[N],b[N];
int c1,c2,c3;
unsigned seed=std::chrono::system_clock::now().time_since_epoch().count();
mt19937 rnd(seed);
vector<int> ans;
vector<int> p;
void rev(int x)
{
ans.push_back(x*2);reverse(a+1,a+x+1);
for (int i=1;i<=x;i++) if (a[i]==1 || a[i]==2) a[i]=3-a[i];
}
void DOIT()
{
scanf("%s",s+1);scanf("%s",t+1);
n=strlen(s+1);n/=2;
c1=c2=c3=0;
for (int i=1;i<=n;i++)
{
if (s[i*2-1]=='0' && s[i*2]=='0') a[i]=0;
if (s[i*2-1]=='0' && s[i*2]=='1') a[i]=1;
if (s[i*2-1]=='1' && s[i*2]=='0') a[i]=2;
if (s[i*2-1]=='1' && s[i*2]=='1') a[i]=3;
if (t[i*2-1]=='0' && t[i*2]=='0') b[i]=0;
if (t[i*2-1]=='0' && t[i*2]=='1') b[i]=1;
if (t[i*2-1]=='1' && t[i*2]=='0') b[i]=2;
if (t[i*2-1]=='1' && t[i*2]=='1') b[i]=3;
if (a[i]==0) c1++;else if (a[i]==3) c2++;else c3++;
if (b[i]==0) c1--;else if (b[i]==3) c2--;else c3--;
}
if (c1!=0 || c2!=0 || c3!=0) {puts("-1");return;}
ans.clear();
for (int i=n;i>=1;i--)
{
if (a[i]==b[i]) continue;
if (a[1]==b[i] && (a[1]==0 || a[1]==3)) {rev(i);continue;}
if (a[1]==3-b[i] && (a[1]==1 || a[1]==2)) {rev(i);continue;}
p.clear();for (int j=1;j<=i;j++) if (a[j]==b[i]) p.push_back(j);
if (p.size())
{
int P=rnd()%p.size();P=p[P];
rev(P);rev(i);
} else
{
for (int j=1;j<=i;j++) if (a[j]==3-b[i]) p.push_back(j);
int P=rnd()%p.size();P=p[P];
rev(P);rev(1);rev(i);
}
}
cout<<ans.size()<<"\n";
for (int x:ans) cout<<x<<" ";cout<<"\n";
}
signed main()
{
int JYZ;rd(JYZ);while (JYZ--) DOIT();
}
/*
*/