hdu1276——双向链表List的使用

题目

给定人数,从1-2报数,报到2的人出列,再从1-3报数,报到3的人出列,如此循环往复,知道队伍中的总人数小于三。

数据结构

使用双向链表存放,满足双向链表的特点:

  1. 插入删除操作频繁
  2. 随机访问较少

算法

List.size()>3时继续循环,使用flag来标记当前报数种类。
停止循环后输出。
每次删除前先计算一共会进行多少次删除操作
如果flag=2的话,每进行一次删除操作(假设现在删除的是第i位),后一位就会前进一位来填补空缺,我们下一位要删除的便是i+1位。
同理可得,当flag=3时,我们下一位要删除的应该是第i+2位。
而退出每一次报数的条件就是当i>l.size()时,退出循环。

细节

这里num++一直在走,但是it++%flag=0时不走,这样就形成一个类似补位的机制,因为list内有元素被释放掉了,后面的元素会向前补一位,这样相当于it已经向前走了一步,所以当满足%flag=0的条件时,num依然++,而lt却不++

代码

#include<iostream>
#include<List>
using namespace std;

int main()
{
    int T;  cin >> T;
    while(T--){
        int n;  cin >> n;
        list<int>l;
        for(int i=1;i<=n;i++){
            l.push_back(i);
        }
        int flag=2;
        while(l.size()>3){
            int num=1;//这里num一定要放在这里定义,因为每一次循环结束,num就需要从1开始
            for(list<int> ::iterator it=l.begin();it!=l.end();){//这里num++一直在走,但是it++在%flag=0时不走,这样就形成一个类似补位的机制,因为list内有元素被释放掉了,后面的元素会向前补一位,这样相当于it已经向前走了一步,所以当满足%flag=0的条件时,num依然++,而lt却不++
                if(  num++  %flag==0){
                    it=l.erase(it);
                }else{
                    it++;
                }
            }
            flag==2?flag=3:flag=2;
        }
        cout << l.front();  l.pop_front();
        while(!l.empty()){
            cout << " ";
            cout << l.front();  l.pop_front();
        }
        cout << endl;
    }
    system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值