题目描述
You have a card deck of n cards, numbered from top to bottom, i. e. the top card has index 1 and bottom card — index n. Each card has its color: the i-th card has color ai.
You should process q queries. The j-th query is described by integer tj. For each query you should:
find the highest card in the deck with color tj, i. e. the card with minimum index;
print the position of the card you found;
take the card and place it on top of the deck.
Input
The first line contains two integers n and q (2≤n≤3⋅105; 1≤q≤3⋅105) — the number of cards in the deck and the number of queries.
The second line contains n integers a1,a2,…,an (1≤ai≤50) — the colors of cards.
The third line contains q integers t1,t2,…,tq (1≤tj≤50) — the query colors. It’s guaranteed that queries ask only colors that are present in the deck.
Output
Print q integers — the answers for each query.
样例输入与输出
7 5
2 1 1 4 3 3 1
3 2 1 1 4
-------------------
5 2 3 1 5
AC Code
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,q;
cin>>n>>q;
vector<int> v(n);
for(int &x:v) cin>>x;
while(q--){
int qu;
cin>>qu;
int p = find(v.begin(),v.end(),qu) - v.begin();
cout<<p+1<<' ';
rotate(v.begin(),v.begin()+p,v.begin()+p+1);
}
return 0;
}
解释
〇Codeforces Educational Round 107 Problem C。解题思路来源于Codeforces Tutorial。
①实际上是一道考察数据结构的题,而又不能使用简单的数据结构。一开始我使用的是链表,思路是,建立一个带有头结点的链表,表头指针代表“纸堆顶”,但惨遭卡时长,慢了几百ms导致后续的测试点RE。下为使用链表的Code:
#include <iostream>
using namespace std;
typedef long long ll;
ll n,m;
struct node{
ll color;
node *next,*prior;
}*h;
void create(int n){
h = new node;
h->color = 0;
h->next = h->prior = NULL;
node *p,*q;
ll x;
while(n--){
cin>>x;
p = new node;
p->color = x;
p->next = p->prior = NULL;
if(!h->next){
h->next = p;
p->prior = h;
}
else{
q->next = p;
p->prior = q;
}
q = p;
}
}
int main()
{
cin>>n>>m;
create(n);
while(m--){
ll t,cnt = 1;
cin>>t;
node *q = h->next;
while(q){
if(q->color == t){
cout<<cnt<<' ';
q->prior->next = q->next;
q->next->prior = q->prior;
h->next->prior = q;
q->next = h->next;
q->prior = h;
h->next = q;
break;
}
q = q->next;
cnt ++;
}
}
return 0;
}
②正解是使用C++自带的vector容器,配合上find方法以及rotate方法,来实现需要的操作。我们分为“输入”,“查找”,“改变位置”三个部分说。
③输入:for(int &x:v) cin>>x;
这一段代码看起来很像Python,因为它隐式地使用了vector中的迭代器进行输入,而这段代码看起来是十分方便的,但是想要这么写,你的编译器需要支持C11标准,如果是DEV,需要进行如下操作来支持C11👇。
👆打开工具栏,选择“编译选项”。
👆红标处打上对勾,再在方框内输入绿标内容,即可使你的Dev支持C11。
④查找:使用find()方法。
如右:int p = find(v.begin(),v.end(),qu) - v.begin();
有三个参数,查找起始位置的迭代器地址,查找终止位置的迭代器地址,以及要查找的内容,find方法返回的是查找目标的迭代器地址,因此需要减去首地址,得到的才是真实位置的索引,而这个索引和数组下标相同,从0开始,因此输出时+1。
⑤置顶:使用rotate()方法。
rotate方法:rotate(v.begin(),v.begin()+p,v.begin()+p+1);
rotate方法同样有三个参数,即将第二个参数和第三个参数之间的段插入到第一个参数位置之前。
⑥AC。