• 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;
    }
  • 相关阅读:
    Linux里的2>&1究竟是什么
    表锁操作
    日志rsyslog
    计划任务at cron
    rpm包管理和源码包管理
    自建yum源(只演示nginx服务,其它都一样)
    软件包管理yum
    文件打包及压缩
    查找文件which locate find
    lsof恢复进程打开的文件
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9451136.html
Copyright © 2020-2023  润新知