P1160 队列安排(链表)
该题采用列表的概念
1、附一些关于链表的相关操作函数
list<int>::iterator it; // 定义一个名为 it 的迭代器(指针)。
l.size(); // 返回链表的节点数量。
l.begin(); // 返回链表头部的迭代器(指针)。
l.end(); // 返回链表尾部的迭代器(指针),指向尾部元素之后的位置。
it++, it--; // 迭代器 it 指向下一个元素(it++)或前一个元素(it--)。
l.push_front(x); // 在链表头部插入元素 x。
l.push_back(x); // 在链表尾部插入元素 x。
l.insert(it, x); // 在迭代器 it 指向的元素前插入元素 x。
l.pop_front(); // 删除链表头部元素。
l.pop_back(); // 删除链表尾部元素。
l.erase(it); // 删除迭代器 it 指向的元素。
for (it = l.begin(); it != l.end(); it++) // 遍历链表元素。
2、思路:
(1)利用mark标记元素是否被删除;利用迭代器标记元素对应的指针,也就是该学生在链表中所处的位置
(2)把1放进去;左(insert)右(先往后移一个,再insert)
(3)删
(4)遍历
3、代码见下:
#include<bits/stdc++.h>
using namespace std;
int n,k,p,m,x;
//标记该位置的人是否已被移去
int mark[100005]={0};
//指向列表的指针
list<int>::iterator it[100005],tempit;
//排列方式
list<int> l;
int main(){
cin>>n;
// 在链表头之前插入元素1
l.push_front(1);
// 返回链表头的指针
it[1]=l.begin();
for(int i=2;i<=n;i++){
cin>>k>>p;
if(p==0){
it[i]=l.insert(it[k],i);
}
else{
// 此处不能直接it[k]++,会导致it[k]代表的指针发生变化
tempit=it[k];
tempit++;
it[i]=l.insert(tempit,i);
}
}
cin>>m;
for(int j=1;j<=m;j++){
cin>>x;
if(mark[x]==1) continue;
l.erase(it[x]);
mark[x]=1;
}
// l.end() 不存储数据,而是一个“虚拟”位置,表示最后一个元素后面的位置
for(tempit=l.begin();tempit!=l.end();tempit++){
cout<<*tempit<<" ";
}
return 0;
}

浙公网安备 33010602011771号