Unshuffling a Deck
Problem Description
You are given a deck of n n n cards numbered from 1 1 1 to n n n (not necessarily in this order in the deck). You have to sort the deck by repeating the following operation.
Choose
2
≤
k
≤
n
2≤k≤n
2≤k≤n and split the deck in k nonempty contiguous parts
D
1
,
D
2
,
…
,
D
k
D_1,D_2,…,D_k
D1,D2,…,Dk (
D
1
D_1
D1 contains the first
∣
D
1
∣
|D_1|
∣D1∣ cards of the deck,
D
2
D_2
D2 contains the following
∣
D
2
∣
|D_2|
∣D2∣ cards and so on). Then reverse the order of the parts, transforming the deck into
D
k
,
D
k
−
1
,
…
,
D
2
,
D
1
D_k,D_{k−1},…,D_2,D_1
Dk,Dk−1,…,D2,D1 (so, the first
∣
D
k
∣
|D_k|
∣Dk∣ cards of the new deck are
D
k
D_k
Dk, the following
∣
D
k
−
1
∣
|D_{k−1}|
∣Dk−1∣ cards are
D
k
−
1
D_{k−1}
Dk−1 and so on). The internal order of each packet of cards
D
i
D_i
Di is unchanged by the operation.
You have to obtain a sorted deck (i.e., a deck where the first card is 1, the second is 2 and so on) performing at most n operations. It can be proven that it is always possible to sort the deck performing at most n operations.
Examples of operation: The following are three examples of valid operations (on three decks with different sizes).
If the deck is [3 6 2 1 4 5 7] (so 3 is the first card and 7 is the last card), we may apply the operation with
k
=
4
k=4
k=4 and
D
1
D_1
D1=[3 6],
D
2
D_2
D2=[2 1 4],
D
3
D_3
D3=[5],
D
4
D_4
D4=[7]. Doing so, the deck becomes [7 5 2 1 4 3 6].
If the deck is [3 1 2], we may apply the operation with
k
=
3
k=3
k=3 and
D
1
D_1
D1=[3],
D
2
D_2
D2=[1],
D
3
D_3
D3=[2]. Doing so, the deck becomes [2 1 3].
If the deck is [5 1 2 4 3 6], we may apply the operation with
k
=
2
k=2
k=2 and
D
1
D_1
D1=[5 1],
D
2
D_2
D2=[2 4 3 6]. Doing so, the deck becomes [2 4 3 6 5 1].
Input
The first line of the input contains one integer n n n ( 1 ≤ n ≤ 52 1≤n≤52 1≤n≤52) — the number of cards in the deck.
The second line contains n integers c 1 , c 2 , … , c n c_1,c_2,…,c_n c1,c2,…,cn — the cards in the deck. The first card is c 1 c_1 c1, the second is c 2 c_2 c2 and so on.
It is guaranteed that for all i = 1 , … , n i=1,…,n i=1,…,n there is exactly one j ∈ 1 , … , n j∈{1,…,n} j∈1,…,n such that c j = i c_j=i cj=i.
Output
On the first line, print the number q q q of operations you perform (it must hold 0 ≤ q ≤ n 0≤q≤n 0≤q≤n).
Then, print q q q lines, each describing one operation.
To describe an operation, print on a single line the number k of parts you are going to split the deck in, followed by the size of the k parts: ∣ D 1 ∣ , ∣ D 2 ∣ , … , ∣ D k ∣ |D_1|,|D_2|,…,|D_k| ∣D1∣,∣D2∣,…,∣Dk∣.
It must hold 2 ≤ k ≤ n 2≤k≤n 2≤k≤n, and ∣ D i ∣ ≥ 1 |D_i|≥1 ∣Di∣≥1 for all i = 1 , … , k i=1,…,k i=1,…,k, and ∣ D 1 ∣ + ∣ D 2 ∣ + ⋯ + ∣ D k ∣ = n |D_1|+|D_2|+⋯+|D_k|=n ∣D1∣+∣D2∣+⋯+∣Dk∣=n.
It can be proven that it is always possible to sort the deck performing at most n operations. If there are several ways to sort the deck you can output any of them.
Sample Input
4
3 1 2 4
Sample Output
2
3 1 2 1
2 1 3
题意
有n张牌,牌面上的数字从1到n,初始n张牌乱序排列。每次操作可以将n张牌分为若干块,块内连续;分块后将这n块逆序排列(块内依然保持原序)。最多操作n次,给出一个能使牌堆升序排列的操作序列。
思路
一种可行的方法是:进行n次操作,每次操作保证至少一张牌被调整到合适的位置。因为每次操作会将块逆序排列,共需进行n次操作,所以,若n为奇数,则依次调整1,n,2,n-1…,若n为偶数,则依次调整n,1,n-1,2…。
已经调整过的,让其保持大小为1的分块即可。依照上述的操作次序,可以保证n次操作后,已调整的部分会在正确的位置上。所以每次操作只需要关心未操作过的那段。设当前未调整的短为[l,r],当前调整的数的下标为x,则将其分为[l,x-1],[x,r]两段(若x==l,则只有一段),即可保证当前数调整到合适的位置。
设
n
=
6
n=6
n=6,序列为
[
4
,
5
,
1
,
3
,
6
,
2
]
[4,5,1, 3, 6, 2]
[4,5,1,3,6,2]。
调整6,分块为[4 2],调整后序列为:[6 2 4 5 1 3];
调整1,分块为[1 3 2],调整后序列为:[1 3 2 4 5 6];
调整5,分块为[1 3 1 1],调整后序列为:[6 5 3 2 4 1];
调整2,分块为[1 1 1 2 1],调整后序列为:[1 2 4 3 5 6];
调整4,分块为[1 1 2 1 1],调整后序列为:[6 5 4 3 2 1];
调整3,分块为[1 1 1 1 1 1],调整后序列为:[1 2 3 4 5 6];
虽然实现起来可能并不太容易操作,但能用就行。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 120;
const int mod = 1000000007;
int a[maxn], b[maxn];
vector<int> g[maxn];
int solve(int n);
void trans(int n, int q);
int main()
{
int n, m, i, j, k;
scanf("%d", &n);
for(i=1;i<=n;i++)
scanf("%d", &a[i]);
k = solve(n);
printf("%d\n", k);
for(i=0;i<k;i++){
printf("%d", g[i].size());
for(j=0;j<g[i].size();j++)
printf(" %d", g[i][j]);
printf("\n");
}
return 0;
}
int solve(int n)
{
int l = 1, r = n, sig, i, j, k, q = 0;
sig = n%2;
while(l<=r)
{
g[q].clear();
if(sig)k = l;
else k = r;
for(i=1;i<=n;i++)
if(a[i] < l || a[i]>r)g[q].push_back(1);
else{
int id;
for(j=i;j<=n && a[j]<=r && a[j]>=l;j++)
if(a[j] == k)id = j;
if(id!=i)g[q].push_back(id-i);
g[q].push_back(j-id);
i = j-1;
}
if(sig)l++;
else r--;
sig = !sig;
if(g[q].size()>1){
trans(n, q);
q++;
}
}
return q;
}
void trans(int n, int q)
{
int i, j, k=n, top = 0;
for(int i=g[q].size()-1;i>=0;i--){
for(j=k-g[q][i]+1;j<=k;j++){
b[++top] = a[j];
}
k -= g[q][i];
}
for(i=1;i<=n;i++)
a[i] = b[i];
}