Easy version
字符串长度n<=1000,可操作次数k<=3*n
Hard version
字符串长度n<=100000,可操作次数k<=2*n
题意: 给你两个二进制串a,b,每次对a操作你可以选择一个长度任意的前缀,在这个区间取反并且反转(0->1 1->0,再reverse),最后让a==b,输出步数及每一步选择的前缀长度,不用最大或最小化操作次数。
思路: easy version可以直接暴力,因为每次取前缀,所以优先匹配后面的,那么以后就不用管后面已经匹配好了的。如果a[i]==b[i]则不用管,否则看a[1]和b[i],如果a[1]==b[i],则先选择长度为1的前缀,让a[1]不等于b[i],再选择长度为i的前缀进行操作,这样就让b[i]成功匹配。
上述操作,遍历b,时间复杂度是O(n),暴力反转时间复杂度也是O(n),嵌套一下就是O(n^2),对于hard肯定不行。
仔细观察可以发现,我们每次操作,要么是让a[i]和b[i]配对,要么是让a[1]和b[i]配对,即每次从首尾去取舍,剩余的总是连续的某一段。所以我们可以用l和r记录剩余串的范围,fg表示这个串的状态,fg=0表示这个串是正向的,并且现在串中数据和原串一样,fg=1表示这个串是反向的,并且串中数组和原来相反,每次反转即改变fg就行了,最后只要从后往前遍历配对一遍b就行了。
easy version代码:
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define pdd pair<double,double>
#define ull unsigned long long
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;}
using namespace std;
const int N=1e3+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-6;
const double PI=acos(-1);
char a[N],b[N];
signed main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
memset(a,0,sizeof a);
memset(b,0,sizeof b);
cin>>a+1;
cin>>b+1;
vector<int>ans;
for(int i=n;i>=1;i--)
{
if(a[i]==b[i])
continue;
if(a[1]==b[i])
{
ans.pb(1);
a[1]=(a[1]=='0'?'1':'0');
}
ans.pb(i);
for(int j=1;j<=i;j++)
{
a[j]=(a[j]=='0'?'1':'0');
}
for(int j=1;j<=i/2;j++)
{
swap(a[j],a[i-j+1]);
}
}
cout<<ans.size()<<' ';
for(auto i:ans)
cout<<i<<' ';
cout<<endl;
}
}
hard version代码:(也适用于easy version)
#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define pii pair<int,int>
#define pdd pair<double,double>
#define ull unsigned long long
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;}
using namespace std;
const int N=1e5+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const double eps=1e-6;
const double PI=acos(-1);
char a[N],b[N];
signed main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
cin>>a+1;
cin>>b+1;
vector<int>ans;
int l=1,r=n,fg=0;
for(int i=n;i>=1;i--)
{
if(fg==0)
{
if(a[r]==b[i])
{
r--;
continue;
}
if(a[l]==b[i])
ans.pb(1);
ans.pb(i);
l++;
fg=1;
}
else
{
if(a[l]!=b[i])
{
l++;
continue;
}
if(a[r]!=b[i])
ans.pb(1);
ans.pb(i);
r--;
fg=0;
}
}
cout<<ans.size()<<' ';
for(auto i:ans)
cout<<i<<' ';
cout<<endl;
}
}