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; 
} 
posted @ 2025-03-25 16:13  夕瑶^  阅读(35)  评论(0)    收藏  举报