洛谷 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。

浙公网安备 33010602011771号