关闭

codeforces 339E Three Swaps 搜索

1076人阅读 评论(0) 收藏 举报
分类:

题目链接

题意:

给定一个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;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1032267次
    • 积分:18993
    • 等级:
    • 排名:第485名
    • 原创:865篇
    • 转载:23篇
    • 译文:0篇
    • 评论:202条
    文章分类
    最新评论
    QQ对话
      QQ
        hello,有问题Q我