zoukankan      html  css  js  c++  java
  • 洛谷 P1160 队列安排

    题目描述

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

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

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

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

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

    输入输出格式

    输入格式:

    第 11 行为一个正整数 NN ,表示了有 NN 个同学。

    第 2-N2N 行,第 ii 行包含两个整数 k,pk,p ,其中 kk 为小于 ii 的正整数, pp 为 00 或者 11 。若 pp 为 00 ,则表示将 ii 号同学插入到 kk 号同学的左边, pp 为 11 则表示插入到右边。

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

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

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    4
    1 0
    2 1
    1 0
    2
    3
    3
    输出样例#1: 复制
    2 4 1
    
    

    说明

    样例解释:

    将同学 22 插入至同学 11 左边,此时队列为:

    2 121

    将同学 33 插入至同学 22 右边,此时队列为:

    2 3 1231

    将同学 44 插入至同学 11 左边,此时队列为:

    2 3 4 12341

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

    2 4 1241

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

    最终队列:

    2 4 1241

    数据范围

    对于 20\%20% 的数据,有 N≤10N10 ;

    对于 40\%40% 的数据,有 N≤1000N1000 ;

    对于 100\%100% 的数据,有 N, M≤100000N,M100000 。

    题意: 开始队列中有一个元素1,然后后面按顺序会给n-1次操作,代表的是第几个数插在哪个数的左边还是右边,后面再删除编号为几的数

     

    思路:一旦插入操作多了之后编号为i的数也不知道左右两边的数是几了,我们如果单纯用数组去模拟的话肯定不行,就是移动位置的操作不太好做,

    我们可以想到用链表移动位置的话只要更改一个指向就好了,然后还有一个问题就是头结点的移动,一定是开始插在1的左边才会更新头节点,再次如果插

    在了新的头结点我们再次更新,详细看代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    struct sss
    {
        int pre;
        int next;
        int value;
    }a[100001];
    int main()
    {
        int n;
        int x,y;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            a[i].value=i;
            a[i].pre=i;
            a[i].next=i;
        }
        int head=1;    
        for(int i=2;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            if(y==0)//更改左右节点和插入节点的指向
            {
                a[i].next=x;
                a[i].pre=a[x].pre;
                a[a[x].pre].next=i;
                a[x].pre=i;
                if(x==head)更新头结点
                {
                    head=i;
                }
            }
            else{
                a[i].pre=x;
                a[i].next=a[x].next;
                a[a[x].next].pre=i;
                a[x].next=i;    
            }
        }
        int m;
        int vis[100001]={0};
        scanf("%d",&m);
        int w=n;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&x);
            vis[x]=1;
        }
        int flag=0;
        while(w--)
        {
        if(vis[head])
            {
                head=a[head].next;
                continue;
            }
            if(flag==0)
            {
                flag=1;
                printf("%d",head);
            }
            else{
                printf(" %d",head);
            }
            head=a[head].next;
        }
    }
  • 相关阅读:
    图片上传-下载-删除等图片管理的若干经验总结3-单一业务场景的完整解决方案
    图片上传-下载-删除等图片管理的若干经验总结2
    HDU 1195 Open the Lock
    HDU 1690 Bus System
    HDU 2647 Reward
    HDU 2680 Choose the best route
    HDU 1596 find the safest road
    POJ 1904 King's Quest
    CDOJ 889 Battle for Silver
    CDOJ 888 Absurdistan Roads
  • 原文地址:https://www.cnblogs.com/Lis-/p/9538880.html
Copyright © 2011-2022 走看看