算法训练营 训练 士兵队列训练(双向链表)

双向链表: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():清空链表
    注意:慎用STLlist,空间复杂度和时间复杂度都容易超出限制。

题目描述

某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队。训练的规则为从头开始进行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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羽星_s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值