【C++】洛谷P1160 队列安排

本文介绍了一种算法,教师如何根据学生编号规则灵活插入和移除同学,以完成最终队伍的编号展示。通过链表实现,适用于学校场景的队列管理问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

队列安排

题目描述

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

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

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

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

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

输入格式

111 行为一个正整数 NNN,表示了有 NNN 个同学。

2∼N2\sim N2N行,第 iii 行包含两个整数 k,pk,pk,p,其中 kkk 为小于 iii 的正整数,ppp000 或者 111。若 ppp 为$ 0$,则表示将 iii 号同学插入到 kkk 号同学的左边,ppp111 则表示插入到右边。

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

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

输出格式

111 行,包含最多 NNN 个空格隔开的正整数,表示了队列从左到右所有同学的编号,行末换行且无空格。

样例 #1

样例输入 #1

4
1 0
2 1
1 0
2
3
3

样例输出 #1

2 4 1

提示

样例解释:

将同学 222 插入至同学 111 左边,此时队列为:

2 1

将同学 333 插入至同学 222 右边,此时队列为:

2 3 1

将同学 444 插入至同学 111 左边,此时队列为:

2 3 4 1

将同学 333 从队列中移出,此时队列为:

2 4 1

同学 333 已经不在队列中,忽略最后一条指令

最终队列:

2 4 1

数据范围

对于 20%20\%20% 的数据,有 1≤N≤101\leq N\leq 101N10

对于 40%40\%40% 的数据,有 1≤N≤10001\leq N\leq 10001N1000

对于 100%100\%100% 的数据,有 1≤N,M≤1000001\leq N,M\leq1000001N,M100000

思路: 用链表储存学生

代码:

#include <bits/stdc++.h>
using namespace std;
struct Student{
    int l, r, del = 0;
} stu[100005];
int main()
{
    int n, m;
    cin >> n;
    stu[1].l = 0, stu[1].r = 0;
    for(int i = 2; i <= n; i++){
        int k, p;
        cin >> k >> p;
        if(p){
            stu[i].l = k;
            stu[i].r = stu[k].r;
            stu[stu[k].r].l = i;
            stu[k].r = i;
        }else{
            stu[i].r = k;
            stu[i].l = stu[k].l;
            stu[stu[k].l].r = i;
            stu[k].l = i;
        }
    }
    cin >> m;
    for(int i = 0; i < m; i++){
        int x;
        cin >> x;
        stu[x].del = 1;
    }
    for(int i = stu[0].r; i; i = stu[i].r){
        if(!stu[i].del) cout << i << " ";
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值