Problem Description
A deck of card consists of n cards. Each card is different, numbered from 1 to n. At first, the cards were ordered from 1 to n. We complete the shuffle process in the following way, In each operation, we will draw a card and put it in the position of the first card, and repeat this operation for m times.
Please output the order of cards after m operations.
Input
The first line of input contains two positive integers n and m.(1<=n,m<=105)
The second line of the input file has n Numbers, a sequence of 1 through n.
Next there are m rows, each of which has a positive integer si, representing the card number extracted by the i-th operation.
Output
Please output the order of cards after m operations. (There should be one space after each number.)
Sample Input
5 3
1 2 3 4 5
3
4
3
Sample Output
3 4 1 2 5
这道题是一个跟输出先后有关的问题,所以首先想到可能会用到,栈、队列、链表这些。比赛过程中,分析了题目特性,得出结论:只需在数字排列序列中(各数字向前排的过程中不删除 e.g.1 2 3 4 5取3得3 1 2 3 4 5)各数字第一次出现的时候进行输出,并开辟一个数组进行标记,下次再遇见输出过的数字进行判断即可。所以根据栈的后进先出原则进行使用。
分析过程中其实我们还试过链表,发现超时,原因是使用过程我们进行了判断并删除的操作,链表在删除时会进行一次遍历,增加了时间复杂度,所以超时,要使用链表也可以,直接使用头插法,其实还是应用了栈的特性。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
using namespace std;
int main()
{
int n,m,k,x,a[100005]={0},b[100005]={0};
cin>>n>>m;
stack<int>s;
for(int i=1;i<=n;i++)
{
cin>>x;
b[i]=x;
}
for(int i=n;i>=1;i--)
{
s.push(b[i]);
}
int c=m;
while(m--)
{
cin>>k;
s.push(k);
}
int temp;
for(int p=1;p<=c+n;p++)
{
temp=s.top();
if(a[temp]!=1)
{
a[temp]=1;
cout<<temp<<" ";
}
s.pop();
}
return 0;
}
注意
使用栈的时候要注意top()和pop()的区别,上述代码中,如果直接让temp=s.pop()是不能编译成功的,因为C++的STL中栈的pop()返回void没有值,所以我们先用top()引用,再用pop()弹出。(写的过中我们出现这个问题还是因为对于栈的函数使用不够清楚,平常关于这个的训练太少了,这次也是学到了)