CF 1427D Unshuffling a Deck

题目描述

https://codeforces.com/problemset/problem/1427/D

Solution

如果序列没有排好序,那么一定存在 $i<j,a_i=a_j+1$

那么我们考虑将序列分成四部分 $[1,i-1],[i,k],[k+1,j],[j+1,n]$

两边有可能是空的,但是并没有影响,注意中间的 $k$ 的作用是不让已经连续的子段分开

也就是我们要找一个 $i\le k< j, a_k>a_{k+1}$,这样每次都使连续的段加 $1$

最多需要做 $n-1$ 次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back
#define maxn 53
using namespace std;

int n, a[maxn], b[maxn], A[maxn];

vector<int> ans[maxn]; int c1;
int main() {
cin >> n; a[0] = 0;
for (int i = 1; i <= n; ++i) cin >> a[i], A[a[i]] = i;
while (1) {
int l = -1, r, k;
for (int i = 1; i < n; ++i)
if (A[a[i] - 1] > i) l = i, r = A[a[i] - 1];
for (int i = l; i < r; ++i)
if (a[i] > a[i + 1]) k = i;
if (l == -1) break; ++c1;

int s1 = l - 1, s2 = k - l + 1, s3 = r - k, s4 = n - r;
for (int i = 1; i <= n; ++i) b[i] = a[i];
for (int i = 1; i <= s4; ++i) a[i] = b[r + i];
for (int i = 1; i <= s3; ++i) a[s4 + i] = b[k + i];
for (int i = 1; i <= s2; ++i) a[s4 + s3 + i] = b[l + i - 1];
for (int i = 1; i <= s1; ++i) a[s4 + s3 + s2 + i] = b[i];
for (int i = 1; i <= n; ++i) A[a[i]] = i;
ans[c1].pb(2 + (s1 > 0) + (s4 > 0));
ans[c1].pb(s1); ans[c1].pb(s2); ans[c1].pb(s3); ans[c1].pb(s4);
}
cout << c1 << endl;
for (int i = 1; i <= c1; ++i, puts(""))
for (auto u : ans[i]) if (u) cout << u << " ";
return 0;
}