Problem C. Yet Another Card Deck及使DevCP支持C11的办法

题目描述

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。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值