题目描述 ingress是一款很好玩的虚(ji)拟(ka)现(ceng)实(fan)游戏,每个玩家都会有Bio Card用来和别的玩家线下交换。 抵抗军特工@PJ10086很喜欢这样的收集,每次线下交换完后他都会得到一个卡堆 。但是他很懒,只会让他的机器人JunJun来整理到他的收 集 里。机器人有三种操作模式:
1. 切换当前操作的卡片到 2. 在 后放置目前的卡片 3. 抛掉 之前的卡 (数据保证 前面一定有卡片可以抛掉) 一天,队友@lszr不小心把他的机器人弄坏了。@PJ10086很生气,让他整理好自己卡堆。@lszr拜托你写一个程序,整理好他的卡堆。 一开始@PJ10086 会拥有一张自己的卡,即“PJ10086”,并且一开始机器人操作的卡片就是“PJ10086”。
输入 多组输入,以文件结束符(EOF)结束。 每组数据第一行输入一个数m( ),表示@PJ10086一共收到的卡牌数量。这些卡片的名称是各不相同的。 接下来m行,每行输入一个整数表示操作模式。 当操作数为1或2时,再输入一个字符串s,表明切换到(增加)了哪一张卡片。 操作1的总和不会超过 的1%。
输出 每组输出一行,表示最终@PJ10086的卡堆顺序,每张卡以空格隔开。
样例输入
6 2 lszr 2 andyhui68666 2 KanModel 2 Mouost 1 KanModel 3 3 2 luhongbin 1 luhongbin 3
{b } i
{a } i
a i
a i b now a i a i−1 a i
m ≤ 300000∑ i
m ∑ i
样例输出
PJ10086 KanModel andyhui68666 lszr luhongbin
提示 该题的输入输出量有可能会很大,请谨慎使用C++的输入输出流。
分析: 还是第一次遇到用到要手写链表的题目。
我这里用的是双向链表。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5;
typedef struct Node{
string name;
struct Node *next,*pre; // 记录前驱和后继
}Node;
struct Link{
Node *root=new Node; // 头节点
Node *now=new Node; // 指向当前当前要操作的卡片
void init(){
Node *temp=new Node;
temp->name="PJ10086"; temp->next=NULL; temp->pre=root;
root->next=temp;
root->pre=NULL;
now->next=temp;
}
void Add(string s){
Node *temp=new Node; temp->name=s;
Node *p=now->next;
if(p->next==NULL) {
temp->next=NULL; temp->pre=p;
p->next=temp;
}else {
temp->next=p->next; temp->pre=p;
p->next ->pre=temp;
p->next=temp;
}
}
void Find(string s){
Node *p;
for(p=root->next;p!=NULL;p=p->next){
if(p->name==s) {
now->next=p;
//cout<<now->next->name<<" ";
break;
}
}
}
void Delete(){
Node *p= now->next;
if(p->pre ->pre ==NULL) return ;
Node *pp=p->pre->pre;
pp->next=p; p->pre=pp;
// delete(p->pre);
}
void Display(){
Node *p=root->next; int have=0;
for(p;p!=NULL;p=p->next){
if(have++) cout<<" ";
cout<<p->name;
}
cout<<endl;
}
}link;
int main(){
int n;
while(cin>>n){
link.init();
// puts("===");
string name; int op;
while(n--){
cin>>op;
if(op==3) link.Delete();
else {
cin>>name; //cout<<name;
if(op==1) link.Find(name);
else
if(op==2) link.Add(name);
}
}
link.Display();
}
return 0;
}
STL 中本身就带有双向链表,我们可以直接调用 ,插入删除的复杂度也是o(1)。
代码
#include<bits/stdc++.h>
using namespace std;
list<string>link;
list<string>::iterator now,t; // now 指向就是要处理的元素
int main(){
int m;
while(cin>>m){
link.clear();
link.push_back("PJ10086"); now=link.begin();
int op;string name;
while(m--){
cin>>op;
if(op==3) {
t=now;
now--; link.erase(now);
now=t;
}else {
cin>>name;
if(op==2) {
t=now;
now++; link.insert(now,name);
now=t;
}
else {
for(t=link.begin();t!=link.end();t++){
if((*t)==name) {
now=t; break;
}
}
}
}
}
int have=0;
for(t=link.begin();t!=link.end();t++){
if(have++) cout<<" ";
cout<<*t;
}
cout<<endl;
}
return 0;
}