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;
}
posted @ 2019-05-18 07:26  风浔凌  阅读(185)  评论(0编辑  收藏  举报