CF936C Lock Puzzle
题目链接:戳我
APIO2019 practice round E题的弱化版
考虑如何构造。
对于一个字符串a:
(未构造好的)+a[pos]+(已构造好的)
1、将已经构造好的按照题目意思翻转,接到前面
(反着的已构造好的)+(未构造好的)+a[pos]
2、将a[pos]按照题目意思翻转(但是因为它就一个数,所以还是不变),接到前面
a[pos]+(反着的已构造好的)+(未构造好的)
3、翻转长度为n,接到前面(因为是所有的了,所以接到前面这一步相当于没有,该操作等效于整体翻转)
(未构造好的)+(已构造好的)+a[pos]
这样子我们就把a[pos]接到已经构造好的后面了。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#define MAXN 100010
using namespace std;
int n;
char a[MAXN],b[MAXN],tmp[MAXN];
vector<int>ans;
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
scanf("%s%s",a+1,b+1);
int len=0,pos,cnt=0;
while(cnt<n)
{
bool flag=false;
for(int i=n-len;i>=1;i--)
{
if(a[i]==b[cnt+1])
{
cnt++,pos=i;
flag=true;
break;
}
}
if(flag==false)
{
printf("-1\n");
return 0;
}
len++;
ans.push_back(n-pos),ans.push_back(1),ans.push_back(n);
int kkk=1;
for(int i=n;i>=pos+1;i--) tmp[++kkk]=a[i];
tmp[1]=a[pos];
for(int i=1;i<pos;i++) tmp[++kkk]=a[i];
reverse(&tmp[1],&tmp[n+1]);
memcpy(a,tmp,sizeof(tmp));
}
printf("%d\n",n*3);
for(int i=0;i<ans.size();i++) cout<<ans[i]<<" ";
return 0;
}