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进行切换
五、剩下的都是符合的,删除会彻底让这个节点消失

浙公网安备 33010602011771号