双向链表:list
list
是一个双向链表,可以在常数时间内插入和删除,不支持数组表示法和随机访问。使用list时,需要引入头文件#include<list>
。
merge(b)
:将链表b
与调用链表合并,在合并之前,两个链表必须已经排序,合并后经过排序的链表被保存在调用链表中,b
为空。remove(val)
:从链表中删除val
的所有节点splice(pos,b)
:将链表b
的内容插入pos
的前面,b
为空reverse()
:将链表翻转sort()
:将链表排序unique()
:将连续的相同元素压缩为单个元素。不连续的相同元素无法压缩,因此一般先排序后去重push_front(x)/push_back(x)
:x
从链表头或尾入pop_front()/pop_back()
:从链表头或尾出front()/back()
:返回链表头或尾元素insert(p,t)
:在p
之前插入t
erase(p)
:删除p
clear()
:清空链表
注意:慎用STL
的list
,空间复杂度和时间复杂度都容易超出限制。
题目描述
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队。训练的规则为从头开始进行1至2报数,凡报2的出列,剩下的向小序号方向靠拢,再从头开始进行1至3报数,凡报3的出列,剩下的向小序号方向靠拢,继续从头开始进行1至2报数…以后从头开始轮流进行1至2报数、1至3报数,直到剩下的人数不超过3人时为止。
输入:包含多和测试用例,第1行为测试用例数N,接着为N行新兵人数(不超过5000)。
输出:单行输出剩下的新兵的最初编号,编号之间有一个空格。
#include <iostream>
#include <list>
int main()
{
using namespace std;
int T,n;
list<int> a;//创建队列
list<int> :: iterator it;//创建队列指针
(cin >> T).get();
while(T--){
(cin >> n).get();
a.clear();//初始化队列
int k = 2;//第一次删除喊“2”的士兵
for (int i = 1; i <= n; ++i) {
a.push_back(i);//存入每个士兵的编号
}
while(a.size()>3){
int cnt = 1;
for (it = a.begin();it != a.end();) {
if(cnt++%k == 0){//删除喊“k”的士兵
it = a.erase(it);//it指向下一位士兵的地址
}
else{
it++;
}
}
k = (k == 2?3:2);
}
for (it = a.begin(); it != a.end(); it++) {
if(it != a.begin()){
cout << " ";
}
cout << *it;
}
cout << endl;
}
return 0;
}
输入:
2
20
40
输出:
1 7 19
1 19 37