1276 “士兵队列训练问题”

问题描述

输入士兵人数n,从头开始进行1到2报数,凡报到2的出列,剩下的数字进行向小序号方向靠拢重组;再从头开始进行1到3的报数,凡报到3的出列,剩下的向小序号方向靠拢重组;

重复这个过程,直到剩下的人数不超过3个为止。

代码如下

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 //链表可以高效的删除和插入
 5 int main()
 6 {
 7     int t,n;
 8     cin>>t; //多组测试
 9     while(t--){
10         cin>>n;           //人数
11         int k = 2;        //初始报数为2
12         list<int> mylist;
13         list<int>::iterator it;
14         for(int i = 1; i <= n; i++){  //赋值从1到n
15             mylist.push_back(i);
16         }
17         while(mylist.size() > 3){
18             int num = 1;  //用于表示顺序过程中的每一个元素
19             for(it = mylist.begin();it!=mylist.end(); ){
20                 if(num++ % k == 0 ){   // 取余的方式用以表示报到2的所有数
21                     it = mylist.erase(it);    //删除,返回下一个对象的指针
22                 }else{
23                     it++;           //跳过
24                 }
25 
26             }
27             k == 2?k=3:k=2;     //交替1到2报数,1到3报数
28         }
29         for(it = mylist.begin(); it != mylist.end();it++){
30             if(it != mylist.begin()){   //不等于第一个数时,输出的内容为空格,每个数之间都有一个空格
31                 cout<<" ";
32             }
33             cout<<*it;   //保留的都是不为2,也不为3的数字
34         }
35         cout<<endl;   //换行
36 
37 
38     }
39 
40     return 0;
41 }

 总结

一、迭代器的创建和使用时需要将开始赋值迭代器

二、取余解决了剔除1到2以及1到3的倍数

三、num顺序变量的比较

四、k==2通过三元运算符合k==3进行切换

五、剩下的都是符合的,删除会彻底让这个节点消失

posted @ 2022-08-15 21:43  暖阳的雪  阅读(54)  评论(0)    收藏  举报