题意:
给定一个1-n的排列
可以选择一个区间将其翻转。至多翻转三次。
问能不能变成单调递增的序列,并输出方案。
题目保证3次翻转一定有解。
思路:
爆搜,每次翻转一段最长的连续区间。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <vector>
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) pt(x / 10);
putchar(x % 10 + '0');
}
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const int N = 1005;
int n, a[N], pos[N];
bool check() {
for (int i = 1;i <= n;i++) if (a[i] != i)return 0;
return 1;
}
int L[6], R[6], top = 0;
bool dfs(int k) {
if (check()){
printf("%d\n", top);
for (int i = top;i;i--)
printf("%d %d\n", L[i], R[i]);
return true;
}
if (k == 3)return false;
for (int i = 1;i <= n;i++)
if (a[i] != i && (abs(a[i] - a[i - 1]) != 1 || abs(a[i] - a[i + 1]) != 1))
for (int j = i + 1;j <= n;j++)
if (a[j] != j && (abs(a[j] - a[j - 1]) != 1 || abs(a[j] - a[j + 1]) != 1))
{
top++;int l = i, r = j;
L[top] = l;R[top] = r;
reverse(a + i, a + 1 + j);
if (dfs(k + 1))return true;
reverse(a + L[top], a + R[top] + 1);
top--;
}
return false;
}
int main() {
rd(n);
for (int i = 1; i <= n; i++)rd(a[i]);
a[0] = a[n + 1] = -1;
dfs(0);
return 0;
}