Codeforces Problem-1579E1 Permutation Minimization by Deque
题目大意:
给出了一个大小为n的排列p。一个大小为n的排列是一个大小为n的数组,其中从1到n的每个整数只出现一次。例如,[1,4,3,2]和[4,2,1,3]是正确的排列,而[1,2,4]和[1,2,2]不是。
让我们考虑一个空的deque(双端队列)。deque是一种支持在开头和结尾添加元素的数据结构。因此,如果deque队列中当前有元素[1,5,2],在开始处添加元素4将生成序列[4,1,5,2],在末尾添加相同的元素将生成序列[1,5,2,4]。
排列的元素依次添加到最初为空的deque队列中,从p1开始,以pn结束。在将每个元素添加到deque之前,您可以选择将其添加到开头还是结尾。
例如,如果我们考虑一个排列p=[3,1,2,4],其中一个可能的动作序列是这样的:
1.在deque的末尾加上3:deque中有一个序列[3];
2.在deque的开头加1:deque中有一个序列[1,3];
3.在deque的后面加2:deque有一个序列[1,3,2];
4.在deque的末尾加上4:deque有一个序列[1,3,2,4];
在处理完整个排列后,在deque中找到按字典顺序可能的最小元素序列。
如果存在i≤n,即x1=y1, x2=y2,…,xi−1=yi−1,xi换句话说,如果序列x和y有一些匹配的前缀(可能是空的),并且序列x的下一个元素严格小于序列y的对应元素。序列[1,3,2,4]比序列[1,3,4,2]小,因为在起始的两个匹配元素[1,3]之后,第一个序列有一个元素2,它比第二个序列中相应的元素4小。
基本思想:
设置一个双向队列deque,依次插入数组中的元素,如果要插入的元素比队头元素小,则插入到队头;反之插入到队尾,最后输出新队列的元素。
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e5+5;
int a[MAXN];
deque<int> q;
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int n;
cin>>n;
for (int i=0;i<n;i++)
cin>>a[i];
for (int j=0;j<n;j++)
{
if (q.empty())
q.push_front(a[j]);
else
{
if (a[j]<q.front())
q.push_front(a[j]);
else
q.push_back(a[j]);
}
}
while (!q.empty())
{
cout<<q.front()<<" ";
q.pop_front();
}
cout<<endl;
}
return 0;
}