我太难了。
发现把第三个放到开头有点鬼畜。
我们来把这个操作规约到我们熟悉的操作。
做一次
我们得到了什么?把
每个数向后移两个位置。
所以我们可以从
依次把
移到
,然后把
这个之前已经排好序的序列用
移到整个序列的最后,如果我们把
移到了
的位置,我们可以用
把
移到
。
这个方法在
时都没有问题。
但是在
时
就行不通了。
所以我们需要在这个时候特判,顺便判断无解。
读者自主完成不难。
#include<bits/stdc++.h>
#define maxn 2005
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
#define per(i,j,k) for(int i=(j);i>=(k);i--)
#define pii pair<int,int>
#define mp make_pair
#define pb emplace_back
using namespace std;
int n,a[maxn];
inline int find(int b){ rep(i,1,n) if(a[i]==b) return i; }
vector<pii >ans,a2;
inline void arg(int l,int r,int t){ static int b[maxn];
rep(i,l,r) b[(i-l+t)%(r-l+1)+l]=a[i];
rep(i,l,r) a[i]=b[i]; }
int main(){
scanf("%d",&n);
rep(i,1,n) scanf("%d",&a[i]);
rep(i,2,n-2){
int p=find(i);
if(a[(p+n-2)%n+1]==i-1) continue;
if(p^1) ans.pb(mp(0,n+1-p)),arg(1,n,n+1-p);
p=find(i-1);
if(p^n){
rep(j,1,(n-p)/2) ans.pb(mp(0,2)),ans.pb(mp(1,1));
bool flg = 0;
if((n-p)&1) ans.pb(mp(0,1)),ans.pb(mp(1,2)),flg=1;
arg(2,n,n-p);
if(flg)
swap(a[2],a[3]);
}
}
if(n&1){
int p=find(n-1);
if(a[(p+n-2)%n+1] ^ (n-2)){ puts("NIE DA SIE");return 0;}
}
int p=find(n);
if(a[(p+n-2)%n+1]^(n-1)){
if(p^1) ans.pb(mp(0,n+1-p)),arg(1,n,n+1-p);
p=find(n-1);
if(p^n){
rep(j,1,(n-p)/2) ans.pb(mp(0,2)),ans.pb(mp(1,1));
arg(2,n,n-p);
}
}
p=find(1);
if(p^1) ans.pb(mp(0,n+1-p));
int cnt = 0;
for(int i=0;i<ans.size();i++)
if(i==ans.size()-1 || ans[i].first ^ ans[i+1].first){
if(ans[i].second % n != 0)
a2.pb(ans[i]);
}
else
ans[i+1].second += ans[i].second;
printf("%d\n",a2.size());
for(int i=0;i<a2.size();i++)
printf("%d%c%c",a2[i].second%n,a2[i].first?'b':'a'," \n"[i==a2.size()-1]);
}