P1160 队列安排(STL-list,splay,树,链表,模拟链表)

传送门

题解:使用STL中的list

迭代器的类型是list<Tp>::iterator(这里模板参数Tp需要与你操作的链表一致)。

迭代器的用法和指针有些像,可以用*运算符访问内部的元素,++和--运算符可以将它后移或前移一位(建议写成前置形式),用==和!=运算符进判断两个迭代器所指的位置是否一致。但要注意:list的迭代器不支持it += x或it1 - it2这样的运算,也不支持<,<=等运算符。

begin()成员函数返回指向头部元素的迭代器。

end()成员函数返回指向末尾位置的迭代器。这个“末尾位置”指的是最后一个元素再往后一位,也就是说end()所指的位置不包含有效元素,它相当于一个虚设的节点。这样设计是为了满足C++标准库表示区间时左闭右开的惯例。

insert(it, val)成员函数用于在链表中插入元素。it为该链表的一个迭代器,val为待插入的值,插入后val位于it所指位置的前一位。返回值为一个迭代器,表示val插入到了哪个位置。

remove(it)成员函数用于删除某个迭代器所指的节点。注意在删除之后it就失效了,除非给it重新赋值,否则对它的任何操作都会导致错误!

除上述主要操作以外,list还提供了其他一些实用的成员函数:size()返回链表内元素的个数,empty()判断链表是否为空,remove(val)用于移除所有值为val的节点,以及作为成员函数的sort()和unique()。(注意sort(myList.begin(), myList.end())是错误的写法)

附上代码:


#include<bits/stdc++.h>

using namespace std;

using Iter=list<int>::iterator;

const int maxn=1e5+10;
Iter pos[maxn];
list<int>quelist;
bool erased[maxn];
int n;

void buildqueue()
{
    quelist.push_front(1);
    pos[1]=quelist.begin();
    for(int i=2;i<=n;i++){
        int k,p;
        scanf("%d%d",&k,&p);
        if(p==0){
            pos[i]=quelist.insert(pos[k],i);
        }else{
            auto nextIter=next(pos[k]);
            pos[i]=quelist.insert(nextIter,i);
        }
    }
    int m;
    scanf("%d",&m);
    int x;
    for(int i=1;i<=m;i++){
        scanf("%d",&x);
        if(!erased[x]){
            quelist.erase(pos[x]);
        }
        erased[x]=true;
    }
}

int main()
{
    scanf("%d",&n);
    buildqueue();
    bool first=true;
    for(list<int>::iterator iter=quelist.begin();iter!=quelist.end();iter++){
        if(!first){
            printf(" ");
        }
        first=false;
        printf("%d",*iter);
    }
    printf("\n");
    return 0;
}

 题解二:模拟链表

题解:使用数组进行模拟链表,和邻接表非常像

//
//#include<bits/stdc++.h>
//
//using namespace std;
//
//using Iter=list<int>::iterator;
//
//const int maxn=1e5+10;
//Iter pos[maxn];
//list<int>quelist;
//bool erased[maxn];
//int n;
//
//void buildqueue()
//{
//    quelist.push_front(1);
//    pos[1]=quelist.begin();
//    for(int i=2;i<=n;i++){
//        int k,p;
//        scanf("%d%d",&k,&p);
//        if(p==0){
//            pos[i]=quelist.insert(pos[k],i);
//        }else{
//            auto nextIter=next(pos[k]);
//            pos[i]=quelist.insert(nextIter,i);
//        }
//    }
//    int m;
//    scanf("%d",&m);
//    int x;
//    for(int i=1;i<=m;i++){
//        scanf("%d",&x);
//        if(!erased[x]){
//            quelist.erase(pos[x]);
//        }
//        erased[x]=true;
//    }
//}
//
//int main()
//{
//    scanf("%d",&n);
//    buildqueue();
//    bool first=true;
//    for(list<int>::iterator iter=quelist.begin();iter!=quelist.end();iter++){
//        if(!first){
//            printf(" ");
//        }
//        first=false;
//        printf("%d",*iter);
//    }
//    printf("\n");
//    return 0;
//}

#include<cstdio>
#include<cstring>
int a[100010][3],n,m;
//a[i][2]表示学号为i的同学右边同学的学号
//a[i][3]表示学号为i的同学左边同学的学号
int main()
{
    scanf("%d",&n);
    int j=1;
    memset(a,0,sizeof(a));
    a[1][1]=1;
    for(int i=2;i<=n;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        a[i][1]=i;
        if(y==0)
        //插入左边
        {
            a[a[x][3]][2]=i;
            a[i][2]=x;
            a[i][3]=a[x][3];
            a[x][3]=i;
            if(x==j) j=i;//最左端
            //比较麻烦,要改链表
        }
        else
        //插入右边
        {
            a[i][2]=a[x][2];
            a[a[x][2]][3]=i;
            a[x][2]=i;
            a[i][3]=x;
        }
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        int x;
        scanf("%d",&x);
        if(a[x][1]!=0)
        //该同学还在
        {
            a[x][1]=0;
            //踢掉……(好可怜)
            a[a[x][3]][2]=a[x][2];
            a[a[x][2]][3]=a[x][3];
            n--;
            if(x==j) j=a[x][3];
        }
    }
    int i=1,x=j;
    while(i<=n)
    {
        printf("%d ",a[x][1]);
        x=a[x][2]; i++;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/82356023