洛谷 P1160 队列安排

题目传送门:

https://www.luogu.com.cn/problem/P1160

 

来说一下本题要用的东西。

list<int> a;定义int类链表。

a.size():链表长度。

a.push_front(x),a.push_back(x):在链表前/后加入x。

a.insert(it,x):(这里的it是迭代器,要提前输入list<int>::iterator it;)在it前面加入

for(it=a.begin();it!=a.end();it++):遍历链表。

本题加入数据是有两种操作,放某数前面或者是后面。但是list中貌似只在某位前放入数据。所以我们就要想办法后置。

后置代码如下:

list<int> a;
list<int>::iterator f[100001];
int x;
auto nextf = next(f[k]);
f[i] = a.insert(nextf, x); 

这里的next是用来获取一个距离指定迭代器 n 个元素的迭代器,常见是next(it,n),可以不输入n,默认是1。

next() 函数的语法格式如下:

template <class ForwardIterator>
ForwardIterator next (ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1);

语法格式不想看没关系,如果想了解更多可以百度一下。

一开始我单纯的以为可以f[k]++。但是WA了。具体看下面:

#include <bits/stdc++.h>
using namespace std;
list<int>::iterator pp[8];
list<int> que;
int main()
{
    que.push_front(1);
    pp[1]=que.begin();
    cout<<&pp[1]<<' ';
    pp[1]++;
    cout<<&pp[1]<<' ';
    auto p=next(pp[1]);
    cout<<&p;
    return 0;
}

输出是:0x515048
    0x515048
    0x7bfe10

可见f[k]++貌似没什么用。

了解了上面的就可以来看完整的AC代码了

#include <bits/stdc++.h>
using namespace std;
list<int> a;         //创建链表
list<int>::iterator f[100001];    //储存各数的位置
list<int>::iterator it;
int san[100001];         //用来记录要删除的值
int n,m;
int main()
{
    cin>>n;
    a.push_front(1);
    f[1]=a.begin();
    for(int i=2;i<=n;i++)
    {
        int k,p;
        cin>>k>>p;
        if(p==0)             //前置代码
        f[i]=a.insert(f[k],i);
        else if(p==1)          //后置代码
        {
          auto nextf = next(f[k]);
          f[i] = a.insert(nextf, i); 
        }
    }
    cin>>m;
    for(int i=0;i<m;i++)      //记录要删除的值
    {
        int j;
        cin>>j;
        san[j]++;
    }
    for(it=a.begin();it!=a.end();it++)       //遍历输出
    {
        if(san[*it]==0)
        cout<<*it<<' ';
    }
    cout<<endl;
    return 0;
}

这个数据较大,所以如果用STL里的find会在最后三个点TLE。

posted @ 2022-07-10 21:32  is_land  阅读(109)  评论(0)    收藏  举报