P6823 「EZEC-4」zrmpaul Loves Array

题目描述

小 Z 有一个下标从 1 开始并且长度为 n 的序列,初始时下标为 i 位置的数字为 i。有 m 个操作,每个操作会是以下四种之一。

  1. 对序列从小到大进行排序。
  2. 对序列从小到大进行排序后将其翻转,(译者注:就是从大到小排序)。
  3. x y 将下标为 x,y 的数交换位置。保证 x≠y且 1≤x,y≤n。
  4. 将序列翻转。

你要输出在 m 次操作后的序列。

输入格式

第一行两个整数 n,m ,表示序列的长度以及操作的数量。
接下来 m 行,每行一个操作。保证操作合法。

输出格式

一行包含 n 个整数,表示操作后的序列。

思路

首先我们从后往前寻找最后一个1 or 2,并从这里开始暴力求解,重点是翻转在最后处理,但暴力操作3时要看翻转了多少次,奇数次逆序,偶数次正序(这里正反序是指这一段的最开始,不管开始的1,2),偶数次交换第x个,第y个,奇数次交换第n-x+1,n-y+1个。
code:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[1000006],b[1000006];
int c[1000006][2];
bool cmp(int a,int b)
{
    
    
 return a>b;
}
int main()
{
    
    
 int n,m,o=1,o2=0;
 cin>>n>>m;
 b[0]=1;
 for (int i=1;i<=m;i++)
 {
    
    
  cin>>b[i];
  if (b[i]==3)
  {
    
    
   cin>>c[i][0]>>c[i][1];
  }
 }
 for (int i=1;i<=n;i++)
 {
    
    
  a[i]=i;
 }
 for (int i=m;i>=0;i--)
 {
    
    
  if (b[i]<=2)
  {
    
    
   o2=i;
   break;
  }
 }
 if (b[o2]==2)
 {
    
    
  sort(a+1,a+1+n,cmp);
 }
 for (int i=o2;i<=m;i++)
 {
    
    
  if (b[i]==3)
  {
    
    
   if (o==1) swap(a[c[i][0]],a[c[i][1]]);
   else swap(a[n-c[i][0]+1],a[n-c[i][1]+1]);
  }
  if (b[i]==4) o=-o;
 }
 int y=(o==1?1:n),y2=(o==1?n:1);
 for (int i=y;i!=y2;i+=o)
 {
    
    
  cout<<a[i]<<' ';
 }
 cout<<a[y2]<<endl;
 return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_49843717/article/details/108540239