339E Three Swaps

传送门

题目大意

给出由1~n组成的序列,每次可将一个区间翻转。问如何从1~n的递增序列变成给出的序列,输出操作次数以及每次操作的区间。最多翻转3次,保证有解,输出任意方案即可。

分析

我们对于每一次翻转只考虑枚举所有可能的点,即我们找出每一段连续区间的两个端点,然后枚举选取这些端点中的哪两个,之后暴力翻转这一段区间即可。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
int a[1100],b[5][1100],nowx[5],nowy[5],n;
inline bool check(){
      int i;
      for(i=2;i<=n;i++)
        if(a[i]!=a[i-1]+1)return 0;
      return 1;
}
inline void pr(int wh){
      int i;
      cout<<wh<<endl;
      for(i=wh;i>0;i--)cout<<nowx[i]<<' '<<nowy[i]<<endl;
      exit(0);
}
inline void dfs(int wh){
      if(check())pr(wh);
      if(wh==3)return;
      int i,j,k;
      int cnt=0;
      b[wh][++cnt]=1;
      for(i=2;i<n;i++)
        if(abs(a[i]-a[i-1])!=1||abs(a[i]-a[i+1])!=1)
          b[wh][++cnt]=i;
      b[wh][++cnt]=n;
      for(i=1;i<cnt;i++)
        for(j=i+1;j<=cnt;j++){
            nowx[wh+1]=b[wh][i],nowy[wh+1]=b[wh][j]; 
              for(k=0;b[wh][i]+k<=b[wh][j]-k;k++)
                swap(a[b[wh][i]+k],a[b[wh][j]-k]);
              dfs(wh+1);
              for(k=0;b[wh][i]+k<=b[wh][j]-k;k++)
                swap(a[b[wh][i]+k],a[b[wh][j]-k]);
        }
      return;
}
int main(){
      int m,i,j,k,x,y;
      scanf("%d",&n);
      for(i=1;i<=n;i++)scanf("%d",&a[i]);
      dfs(0);
      return 0;
}
原文地址:https://www.cnblogs.com/yzxverygood/p/9451136.html