题目要求
某部队进行新兵队列训练,将新兵从1开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始1至2报数,凡报到2的出列,剩下的向小序号方向靠拢,再从头开始进行1至3报数,凡报到3的出列,剩下的向小序号方向靠拢,继续从头开始进行1至2报数,以后从头开始轮流进行1至2报数、1至3报数直到剩下的人数不超过三人为止。编写程序,输入数N为最开始的新兵人数(20 < N < 6000),输出剩下的新兵最初的编号。
输入样例:
21
输出样例:
1 7 19
思路:
第一次把2的倍数全部删除,更新后把三的倍数全部删除,以此循环
方法:
1.用队列(后续补充)
2.链表+STL
代码:
#include <iostream>
#include<list>
using namespace std;
int main()
{
list<int>llist;
list<int>::iterator it;//设置迭代器的固定形式,it被用作链表的下标
int n,k=2;
cin>>n;
for(int i=1;i<=n;i++)
llist.push_back(i);//push_back函数,在链表的末尾插入一个元素
while(llist.size()>3)
{
int count=0;
for(it=llist.begin();it!=llist.end();)//为防止迭代器断掉,此处不可加循环,而是手动加;
{
count++;
if(count%k==0)
it=llist.erase(it);//可以理解为固定操作,erase的作用是,使作为参数的迭代器失效,
//并返回指向该迭代器下一参数的迭代器。
//如果只是llist.ersea(it);此时的it就失效了,迭代器就断了
else
it++;
}
if(k==2)
k=3;
else
k=2;
}
for(it=llist.begin();it!=llist.end();it++)
{
if (it!=llist.begin()) cout<<" ";
cout<<*it;
}
cout<<endl;
}
代码补充知识
- STL中库函数应用,详情见List应用
使用时 listname.functionname()
这里列几个用到的:
1 .push_back():尾部插入
pop_back():尾部删除 类似push_front;pop_front;
2 .begin();end()
3 .迭代器 list::iterator it;当成固定格式来记,iterator
4 .erase()删除函数,详情见ersea函数
正确用法:pointer = ParticleSystem.erase(pointer);
或者test_list.erase(test_list_it++);
但是test_list.erase(test_list_it);
这样就得寄;让迭代器断连了 - for循环的顺序
for(条件①;条件②;条件③)
{循环体④
}
执行顺序如下:
①②④③ ②④③ ②④③… …直到结束