zoukankan      html  css  js  c++  java
  • P1160 队列安排题解

    题目传送门

    一、双链表示意图

    二、C++代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    //双链表模板
    const int N = 100010;
    
    int e[N]; //数据
    int l[N]; //左链表
    int r[N]; //右链表
    int idx;  //准备放入的索引值
    
    //正整数x,表示将x号同学从队列中移去,如果x号同学已经不在队列中则忽略这一条指令。
    //正是因为有了这句话,如果没有删除的标识了,真的有重复指令就会让数据出问题。
    // 因为可能重复的对左右结点进行操作,造成数据错误。
    int st[N]; //删除标识
    // 黄海写的题解
    // https://www.acwing.com/solution/content/35794/
    
    //0表示头,1表示尾,正式使用的是从idx=2开始
    void init() {
        //0的右端是1,1的左端是0
        r[0] = 1, l[1] = 0, idx = 2;
    }
    
    //函数含义:在k号节点右侧插入,值为x
    //如果想实现:在k号节点左侧插入,值为x  则调用:add(l[k],x),意义为在k的左侧,
    //相当于在k的左侧节点的右侧,
    void add(int k, int x) {
        e[idx] = x; //将x放入到一个空的单元格中
        l[idx] = k; //将新增加的单元格的右指针指向k的下一链路节点
        r[idx] = r[k];  //将新增加的单元格的左指针指向k
        //完成上面两步后,只是让idx这个节点建立了与原来两个节点的关系,而原来的两个k与r[k],
        // l[r[k]]还是旧的值,也需要进行修改。
        l[r[k]] = idx;
        r[k] = idx;
        //为下一次做准备
        idx++;
    }
    
    //删除第k个节点
    void remove(int k) {
        r[l[k]] = r[k];
        l[r[k]] = l[k];
    }
    
    int n, k, p, m, x;
    
    
    //输出双链表
    void print() {
        //遍历双向链表的方法
        for (int i = r[0]; i != 1; i = r[i]) cout << e[i] << " ";
        cout << endl;
    }
    
    int main() {
        //初始化双链表
        init();
    
        //读入
        cin >> n;
    
        //先将1号同学安排进队列
        //最左端就是表示在head(0号)的右侧插入一个数据
        add(0, 1);
        for (int i = 2; i <= n; i++) {
            //k为小于i的正整数
            cin >> k >> p;
            //p为0,表示将i号同学插入到k号同学的左边
            //p为1,表示将i号同学插入到k号同学的右边
    
            //idx从2开始,所以下标需要k+1传入才对
            //就是1号同学的idx=2
            //就是2号同学的idx=3
            //就是3号同学的idx=4
            //就是k号同学的idx=k+1
            //右边就是正常的add(k+1,i)
            //左边稍有一点变化:add(l[k+1],i), 表示在当前号的左侧那个,就是它的前面结点的右侧放入
            if (p == 0) add(l[k + 1], i);
            else add(k + 1, i);
        }
        //表示去掉的同学数目
        cin >> m;
        for (int i = 1; i <= m; i++) {
            cin >> x;
            //表示将x号同学从队列中移去
            if (!st[x + 1]) {
                remove(x + 1);
                st[x + 1] = 1;
            }
        }
        //输出链表 (表示了队列从左到右所有同学的编号,行末换行且无空格)
        print();
        return 0;
    }
    
  • 相关阅读:
    【转】HBase中的时间维度
    【转】HBase基本原理
    【转】BloomFilter——大规模数据处理利器
    【转】HBase客户端API:管理特性
    es6 模本字符串拼接方法 ``
    Electron桌面应用打包流程
    vue-electron脚手架安装及说明 打包基于Vue的 桌面应用程序
    safari打开的页面数字识别变为蓝色
    使用jquery中$.each()方法来循环一个数据列表
    jquery实现点击控制div的显示和隐藏
  • 原文地址:https://www.cnblogs.com/littlehb/p/15074916.html
Copyright © 2011-2022 走看看