题意:
给定一个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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-11 19:31:08