题目链接:http://http://codeforces.com/problemset/problem/339/E
题意:
给出由1~n组成的序列,每次可将一个区间翻转
问如何从1~n的递增序列变成给出的序列,输出操作次数以及每次操作的区间
最多翻转3次,保证有解,输出的操作次数不一定是最小的
解题思路:
每次先翻转最长的连续区间
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <math.h>
#include <algorithm>
using namespace std;
int a[1005];
int n,top=0;
struct node
{
int li,ri;
}p[5];
bool check()
{
for(int i=1;i<=n;i++)
{
if(a[i]!=i) return 0;
}
return 1;
}
bool dfs(int k)
{
if(check())
{
printf("%d\n",top);
for(int i=top;i>=1;i--)
{
printf("%d %d\n",p[i].li,p[i].ri);
}
return true;
}
if(k==3) return false;
for(int i=1;i<=n;i++)
{
int t1=abs(a[i]-a[i-1]);
int t2=abs(a[i]-a[i+1]);
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++)
{
int t3=abs(a[j]-a[j-1]);
int t4=abs(a[j]-a[j+1]);
if(a[j]!=j && (abs(a[j]-a[j-1])!=1 || abs(a[j]-a[j+1])!=1))
{
top++;
p[top].li=i;
p[top].ri=j;
reverse(a+i,a+j+1);
if(dfs(k+1)) return true;
reverse(a+p[top].li,a+1+p[top].ri);
top--;
}
}
}
}
return false;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
a[0]=a[n+1]=-1;
top=0;
dfs(0);
return 0;
}