P1160 队列安排
第一版:
- 思路:
- 使用链表 c++ 的list库
- 插入的时候遍历查找,然后插入
- 删除的时候使用list.remove()进行删除
- 结果:后三个超时
- 源码:
#include<iostream>
#include<list>
using namespace std;
list<int> ls;
int n;
int main(){
// freopen("data.in","r",stdin);
cin>>n;
ls.push_back(1);
int t1,t2;
list<int>::iterator it;
for(int i=2;i<=n;i++){
cin>>t1>>t2;
for(it=ls.begin();it!=ls.end();it++){
if(*it==t1){
if(t2==0){
// 左边
ls.insert(it,i);
}else{
// 右边
ls.insert(++it,i);
}
break;
}
}
}
cin>>n;
while(n--){
cin>>t1;
ls.remove(t1);
}
while(!ls.empty()){
n = ls.front();
ls.pop_front();
cout<<n;
if(ls.size()!=0)
cout<<" ";
}
cout<<endl;
return 0;
}
- 问题分析:
- 每次插入都要遍历一遍,插入的时间复杂度O(n^2)
- 删除的时候不确定,没去查源码
第二版:
本次解法参考(照抄)了 Orina_zju 的解法,
-
思路:
-
既然每次插入花费了大量时间,那就想办法减少时间花费,大牛使用一个iterator数组的方法直接记录每个学生对应的iterator,使得insert的时候不需要遍历查找,节省了插入的时间
插入后的迭代器 insert(迭代器,插入值); // 大牛的方法 ls<int> ls; list<int>::iterator pos[100003]; pos[新插入的同学的编号] = ls.insert(pos[被插入的同学的编号],新插入的同学的编号) // 当新插入的是右边时,可以使用迭代器中的next方法 pos[新插入的同学的编号] = ls.insert(next(pos[被插入的同学的编号]),新插入的同学的编号)本蒟蒻这还是第一次接触到迭代器的这些方法...
-
删除的时候使用erase(iterator)的方式,由于记录的有每个同学的iterator,所以也省去了遍历的时间
这里新增了一个数组,记录是否删除过了,因为如果不进行记录,虽然数值不会被重复删除,但是ls的数量会不对,以本体测试用例为例,
ls.erase(its[3]); ls.erase(its[3]); cout<<"size is "<<ls.size()<<endl; while(!ls.empty()){ cout<<ls.front()<<endl; ls.pop_front(); } /* 输出: size is 2 2 4 1 */所以,需要一个bool数组记录是否删除过
bool used[100000+5];// [1,n]初始化为true while(n--){ cin>>t1; if(used[t1]){ ls.erase(its[t1]); used[t1] = false; } }
-
-
完整代码
#include<iostream> #include<list> using namespace std; list<int> ls; list<int>::iterator its[100000+5]; int n; bool used[100000+5]; int main(){ freopen("data.in","r",stdin); cin>>n; ls.push_back(1); its[1] = ls.begin(); used[0] = used[1] = true; int t1,t2; list<int>::iterator it; for(int i=2;i<=n;i++){ cin>>t1>>t2; if(t2==0){ // 左边,正常插入 its[i] = ls.insert(its[t1],i); }else{ // 右边 its[i] = ls.insert(next(its[t1]),i); } used[i] = true; } cin>>n; while(n--){ cin>>t1; if(used[t1]){ ls.erase(its[t1]); used[t1] = false; } } while(!ls.empty()){ n = ls.front(); ls.pop_front(); cout<<n; if(ls.size()!=0) cout<<" "; } cout<<endl; return 0; }