P1160 队列安排题解

题目

一个学校里老师要将班上N个同学排成一列,同学被编号为1∼N,他采取如下的方法:

  1. 先将1号同学安排进队列,这时队列中只有他一个人;

  2. 2∼N号同学依次入列,编号为i的同学入列方式为:老师指定编号为i的同学站在编号为1∼(i−1)中某位同学(即之前已经入列的同学)的左边或右边;

  3. 从队列中去掉M个同学,其他同学位置顺序不变。

在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。

输入输出格式

输入格式

第一行一个整数N,表示了有N个同学。 

第2∼N行,第i行包含两个整数k,p,其中k为小于i的正整数,p为0或者1。若p为0,则表示将i号同学插入到k号同学的左边,p为1则表示插入到右边。

第N+1行为一个整数M,表示去掉的同学数目。

接下来M行,每行一个正整数x,表示将x号同学从队列中移去,如果x号同学已经不在队列中则忽略这一条指令。

输出格式

一行,包含最多N个空格隔开的整数,表示了队列从左到右所有同学的编号。

输入输出样例

输入样例

4
1 0
2 1
1 0
2
3
3

输出样例

2 4 1

补充知识

链表的使用,可以完成以下的操作,实现一个数据结构,维护一张表(最初只有一个元素1)。支持以下的操作,其中x,y都是int范围内的正整数,且都不一样。

(1)ins_back(x,y):将元素y插入到x后面

(2)ins_front(x,y):将元素y插入到x前面

(3)ask_back(x):询问x后面的元素

(4)ask_front(x):询问x前面的元素

(5)del(x):从表中删除元素x,不改变其他元素的先后顺序

struct node{int pre,nxt;//分别记录前驱和后继结点在数组s中的下标int key;node(int _key=0,int _pre=0,int _nxt=0){pre=_pre;nxt=_nxt;key=_key;}
};
node s[100005];
//一个池,以后想要新建一个结点,就从s数组里面拿出一个位置给新结点
//也可以使用指针new,delete实现
int tot=0;//记录s数组目前使用了多少个位置,那么下一个可用的位置就是s[tot+1]
int find(int x){//查找x的结点编号,需要遍历整个链表int now=1;while(now&&s[now].key!=x){now=s[now].nxt;return now;} 
} 
void ins_back(int x,int y){//y插在x后面 int now=find(x);s[++tot]=node(y,now,s[now].nxt);s[s[now].nxt].pre=tot;s[now].nxt=tot;
}
void ins_front(int x,int y){//y插在x前面 int now=find(x);s[++tot]=node(y,s[now].pre,now);s[s[now].pre].nxt=tot;s[now].pre=tot;
}
int ask_back(int x){int now=find(x);return s[s[now].nxt].key;
}
int ask_front(int x){int now=find(x);return s[s[now].pre].key;
}
void del(int x){int now=find(x);int le=s[now].pre,rt=s[now].nxt;s[le].nxt=rt;s[rt].pre=le;
}

当然STL库也提供了链表的相关操作,需要使用list的头文件。支持以下的常用方法。

(1)list<int> a:定义一个int类型的链表a

(2)int arr[5]={1,2,3};lsit<int> a(arr,arr+3):从数组arr中的前三个元素作为链表a的初始值

(3)a.size():返回链表的结点数量

(4)list<int>::iterator it:定义一个名为it的迭代器(指针)

(5)a.begin();a.end():链表开始和末尾的迭代器指针

(6)it++;it--:迭代器指向前一个和后一个元素

(7)a.push_front(x);a.push_back():在链表开头或者末尾插入元素x

(8)a.insert(it,x):在迭代器it的前插入元素x

(9)a.pop_front();a.pop_back():删除链表开头或者末尾

(10)a.erase(it):删除迭代器it所在的元素

(11)for(it=a.begin();it!=a.end();it++):遍历链表

解析

此题目利用一个双向链表维护这个队伍,每个同学记录自己左边和右边的同学。这样各种操作都可以O\left ( 1 \right )的复杂度完成。可以使用上面的链表模板,但是需要稍微修改一下插入函数和删除函数。使用数组index定位某位同学的结点编号,在插入和删除时直接找到这位同学的结点编号,在插入时还要记录下这名同学的结点编号。这样就不需要每次都要遍历整个链表了。

#include<iostream>
using namespace std;
struct node{int pre,nxt,key;node(int _key=0,int _pre=0,int _nxt=0){pre=_pre;nxt=_nxt;key=_key;}
};
node s[100005];
int n,m,tot=0,index[100005]={0};//记录每个位置的结点编号
void ins_back(int x,int y){int now=index[x];//查找索引s[++tot]=node(y,now,s[now].nxt);s[s[now].nxt].pre=tot;s[now].nxt=tot;index[y]=tot;//记录索引
}
void ins_front(int x,int y){int now=index[x];s[++tot]=node(y,s[now].pre,now);s[s[now].pre].nxt=tot;s[now].pre=tot;index[y]=tot;
}
void del(int x){int now=index[x];int le=s[now].pre,rt=s[now].nxt;s[le].nxt=rt;s[rt].pre=le;index[x]=0;
}
int main(){int x,k,p,now;cin>>n;s[0]=node();//令0恒为最左边的结点ins_back(0,1);for(int i=2;i<=n;i++){cin>>k>>p;p ? ins_back(k,i):ins_front(k,i);}cin>>m;for(int i=1;i<=m;i++){cin>>x;if(index[x]){del(x);}}now=s[0].nxt;while(now){cout<<s[now].key<<" ";now=s[now].nxt;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/512639.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux实践室】Linux常用命令

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;Linux实践室、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️任务描述二. ⛳️相关知识2.1 &#x1f514;Linux文件操作2.1.1 &#x1f47b;创建文件2…

请说说你对Vue模板编译的理解

Vue模板编译是Vue.js框架的核心之一&#xff0c;它负责将Vue模板转换成渲染函数&#xff0c;从而实现模板的解析和渲染。要深入了解Vue模板编译&#xff0c;我们需要从编译过程、作用、特点等方面进行详细解析。 1. Vue模板编译的作用 Vue模板编译的主要作用是将Vue模板字符串…

软件测试 - 测试用例基本理论

1. 概念 为了特定的目的(该目的是检验代码是否满足用户需求)而设计的文档&#xff0c;文档包含测试输入、执行条件、预期结果等。文档的形式一般是excel表格。 比如说我们买了一台电脑&#xff0c;新买的笔记本检查完外观之后第一步需要查看电脑是否能够正常开机&#xff0c;…

DevOps中集成自动化测试的具体案例

在DevOps中集成自动化测试的具体案例可以从多个角度进行分析,包括金融行业、分布式系统、大型企业等不同领域的实践。以下是几个具体的案例: 金融行业的DevOps实践:在金融行业中,DevOps被广泛应用于提升软件开发和运营的效率。例如,通过解析后台接口代码日志格式,自动化生…

PostgreSQL restartpoint 原理详解

背景 大部分人对 PG 的 checkpoint 机制会熟悉一点&#xff0c;但是对 restartpoint 却不太熟悉&#xff0c;网上介绍这方面的文章也比较少。因此&#xff0c;本文将以 PG 14.7 的社区代码为基础&#xff0c;介绍 PG 中的 restartpoint 机制。 原理介绍 什么是 restartpoint…

【ArcPy】游标访问几何数据

访问质心坐标相关数据 结果展示 代码 import arcpy shppath r"C:\Users\admin\Desktop\excelfile\a2.shp" with arcpy.da.SearchCursor(shppath, ["SHAPE","SHAPEXY","SHAPETRUECENTROID","SHAPEX","SHAPEY",&q…

Oracle.xs.dll‘ for module DBD::Oracle: load_file:找不到指定的模块

安装Ora2pg时,碰到 异常现象 D:\ProgramFiles\ora2pg>ora2pg -t show_report --estimate_cost -c ora2pg_conf.dist install_driver(Oracle) failed: Cant load D:/ProgramFiles/strawberry/perl/site/lib/auto/DBD/Oracle/Oracle.xs.dll for module DBD::Oracle: load_fil…

【AI视野·今日CV 计算机视觉论文速览 第300期】Fri, 1 Mar 2024

AI视野今日CS.CV 计算机视觉论文速览 Fri, 1 Mar 2024 Totally 114 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers DistriFusion: Distributed Parallel Inference for High-Resolution Diffusion Models Authors Muyang Li, Tianle Cai, J…

Linux 学习笔记(11)

十一、 资源监控 1 、 free 内存监控 语 法&#xff1a; free [-bkmotV][-s < 间隔秒数 >] 补充说明&#xff1a; free 指令会显示内存的使用情况&#xff0c;包括实体内存&#xff0c;虚拟的交换文件内存&#xff0c;共享内存区段&#xff0c;以 及系统核心使用的…

linux kernel物理内存概述(五)

目录 概述 一、快速路径分配 1、get_page_from_freelist 2、rmqueue()函数 二、慢速路径分配 1、分配流程 三、direct_compact 概述 物理内存分配步骤 1、初始化,参数初始化 2、内存充足&#xff0c;快速分配 get_page_from_freelist 3、内存压力大&#xff0c;慢速…

大模型学习笔记五:RAG

文章目录 一、RAG介绍1)局限性2)通过检索增强生成二、RAG系统的基本搭建流程1)搭建流程简介2)文档的加载和切割3)检索引擎4)LLM接口封装5)prompt模板6)RAG Pipeline初探7)关键字检索局限性三、向量检索1)文本向量2)向量相似度计算3)向量数据库4)基于向量检索的RAG…

基于springboot+vue的医院药品管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…