CodeForces_1427D Unshuffling a Deck(构造)

Unshuffling a Deck

time limit per test:1 seconds
memory limit per test:256 megabytes
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 2kn 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,Dk1,,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}| Dk1 cards are D k − 1 D_{k−1} Dk1 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 1n52) — 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} j1,,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 0qn).

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 2kn, and ∣ D i ∣ ≥ 1 |D_i|≥1 Di1 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];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值