牛客~~wannafly挑战赛19~A 队列

链接:https://www.nowcoder.com/acm/contest/131/A
来源:牛客网

题目描述

ZZT 创造了一个队列 Q。这个队列包含了 N 个元素,队列中的第 i 个元素用 Q i 表示。Q 1 表示队头元素,Q N 表示队尾元素。队列中的元素是 N 的一个全排列。

ZZT 需要在这个队列上执行 P 次操作,操作分两种:
FIRST X: 将元素 X 移到队头。
LAST X: 将元素 X 移到队尾。

在 P 次操作之后,ZZT 想知道队列中的元素的排列方式,由于他最近很忙,因此需要请你帮他解决这个问题。

输入描述:

第一行输入一个正整数 N,表示队列的大小。
第二行输入 N 个正整数,Q
1
, Q
2
, Q
3
, ... ..., Q
N
,Q
i
 表示队列中的第 i 个元素。保证这 N 个数是 N 的一个全排列。
第三行输入一个正整数 P,表示接下来要进行的操作次数。
接下来 P 行,第 i 行输入一个字符串 S i 以及一个正整数 X i,表示一次操作。
1 ≤ N ≤ 10 5.
1 ≤ Q i ≤ N.
1 ≤ P ≤ 10 5.
S  { “FIRST”, “LAST” }.
1 ≤ X i ≤ 10 5.

输出描述:

输出 N 个正整数,表示 P 次操作之后的队列。
示例1

输入

复制
4
4 2 1 3
3
FIRST 4
LAST 2
LAST 1

输出

复制
4 3 2 1
题意:中文题很明了了,要求对一长度为n的=队列进行m次操作,将指定元素插在队头或者队尾
题解:我们用两个数组进行保存和一个set容器进行操作
先将数据和操作分别读入
因为我们可以知道,操作从前往后会将数据不断的往队列里面压缩,所以我们将操作存起来倒着操作
这样就可以保证元素的顺序
用set容器来维护,确保临时数组b中没有重复元素出现
代码如下
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn=1e5+5;
int a[maxn], b[maxn];
set<int> s;
char ins[maxn][10];
int v[maxn];
int main(){
    int n;
    scanf("%d", &n);
    for(int i=0;i<n;i++)
        scanf("%d", &a[i]);
    int m;
    scanf("%d", &m);
    for(int i=0;i<m;i++){
        scanf("%s%d", ins[i], &v[i]);
    }
    int head=0, tail=n-1;
    //从0开始的头部操作和从n-1开始的尾部操作,分别插入
    //tips:操作完后b数组中可能有空的位置没有被占据
    
    for(int i=m-1;i>=0;i--){
        int val=v[i];
        if(s.count(val)){
            continue;
        }
        s.insert(val);
        if(ins[i][0]=='F'){
            b[head++]=val;
        }else{
            b[tail--]=val;
        }
    }

    //我们将a中没有插入到b中的数组插入到b中
    for(int i=0;i<n;i++)
    if(!s.count(a[i])){
        b[head++]=a[i];
    }
    head=0;
    //重新插入覆盖,保证队列的完整性
    for(int i=0;i<n;i++)
    if(b[i]!=0){
        a[head++]=b[i];
    }
    //格式要求很重要
    for(int i=0;i<head;i++)
        printf("%d%c", a[i], i==n-1?'\n':' ');
 
    return 0;
}
View Code


猜你喜欢

转载自www.cnblogs.com/buerdepepeqi/p/9277164.html