洛谷-P1160 队列安排

本文介绍了一种利用双向链表解决学生队列排列问题的方法。通过数组实现的双向链表,有效地处理了学生入队及出队的操作,并提供了两种不同的实现方案。

题目

Problem Description

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

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

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

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

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

 

Input

输入文件arrange.in的第1行为一个正整数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号同学已经不在队列中则忽略这一条指令。

 

Output

输入文件arrange.out仅包括1行,包含最多N个空格隔开的正整数,表示了队列从左到右所有同学的编号,行末换行且无空格。
 

Sample Input

4
1 0
2 1
1 0
2
3
3

 

Sample Output

2 4 1

 


题解

  纯粹是为了练一练数据结构中的双向链表的写法而选择的这道题,结果用malloc和指针实现的双向链表反而找不出好的方法,反而用数组实现的AC了……但是还是把40分的超时代码记下来,可能以后数据结构考试会用到吧……

  100分代码非常简单,但我可能写的还是不够简单。因为数据是按顺序且不重复给出的,所以用数组下标可以很好的知道储存的位置。相反,如果只用指针,一个一个找起来就会超时……


代码

100分代码:

#include <iostream>
using namespace std;
int n,m;
int used[100005];
struct DuLinkList{
    int prior;
    int next;
}dll[100005];
int main(){
    int k;
    bool t;
    cin >> n;
    dll[0].next=1;
    dll[0].prior=-1;
    dll[1].prior=0;
    dll[1].next=-1;
    for(int i=2;i<=n;i++){
        cin >> k >> t;
        if(t){
            dll[dll[k].next].prior=i;
            dll[i].next=dll[k].next;
            dll[k].next=i;
            dll[i].prior=k;
        }
        else{
            dll[dll[k].prior].next=i;
            dll[i].prior=dll[k].prior;
            dll[k].prior=i;
            dll[i].next=k;
        }
    }
    cin >> m;
    for(int i=1;i<=m;i++){
        cin >> k;
        if(used[k]!=1){
            used[k]=1;
            dll[dll[k].prior].next=dll[k].next;
            dll[dll[k].next].prior=dll[k].prior;
        }
    }
    for(int i=0;dll[i].next!=-1;i=dll[i].next){
        cout << dll[i].next;
        if(dll[dll[i].next].next!=-1)
            cout << " ";
        else
            cout << endl;
    }
    return 0;
}

40分代码:

#include <iostream>
#include <stdlib.h>
#include <math.h>

using namespace std;

typedef int Status;
typedef int ElemType;

class DLL{
public:
    void InitList(){
        L=(DuLNode*)malloc(sizeof(DuLNode));
        L->data=1;
        L->prior=NULL;
        L->next=(DuLNode*)malloc(sizeof(DuLNode));
        L->next->data=1;
        L->next->prior=L;
        L->next->next=NULL;
    }
    void DestroyList(){
        DuLNode *p,*q;
        p=L;
        while(p->next!=NULL){
            q=p->next;
            free(p);
            p=q;
        }
    }
    int LocateElem(ElemType e){
        int i=0;
        DuLNode *p=L;
        while(p->next!=NULL)
        {
            p=p->next;
            i++;
            if(p->data==e)
                return i;
        }
        return 0;
    }
    void ListInsert(int i,ElemType e,bool t)
    {
        DuLNode *p,*s;
        p=GetElemP(i);
        s=(DuLNode*)malloc(sizeof(DuLNode));
        if(t==1){
            s->data=e;
            s->prior=p;
            s->next=p->next;
            if(p->next!=NULL)  //这句话好重要啊……
                p->next->prior=s;
            p->next=s;
        }
        else{
            s->data=e;
            s->next=p;
            s->prior=p->prior;
            p->prior->next=s;
            p->prior=s;
        }
        L->data++;
    }
    void ListDelete(int i)
    {
        DuLNode *p;
        p=GetElemP(i);
        p->prior->next=p->next;
        if(p->next!=NULL)  //这句话好重要啊……
            p->next->prior=p->prior;
        free(p);
        L->data--;
    }
    void PrintList(){
        DuLNode *p=L;
        for(int i=1;i<L->data;i++){
            p=p->next;
            cout << p->data << " ";
        }
        p=p->next;
        cout << p->data << endl;
    }
private:
    struct DuLNode{
        ElemType data;
        DuLNode *prior;
        DuLNode *next;
    };
    DuLNode *L;
    int ListLength(){
        return L->data;
    }
    DuLNode* GetElemP(int i){
        DuLNode *p=L;
        for(int j=1;j<=i;j++)
            p=p->next;
        return p;
    }
};

DLL l;

int m,n;

int main(){
    int k;
    bool p;
    cin >> n;
    l.InitList();
    for(int i=1;i<n;i++){
        cin >> k >> p;
        l.prioristInsert(l.priorocateElem(k),i+1,p);
    }
    cin >> m;
    for(int i=1;i<=m;i++){
        cin >> k;
        if(l.priorocateElem(k)!=0)
            l.prioristDelete(l.priorocateElem(k));
    }
    l.PrintList();
    l.DestroyList();
    return 0;
}

 

转载于:https://www.cnblogs.com/skl-hray/p/7642485.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值