题目
n个人围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
输入输出格式
输入格式
输入两个整数n,m。
输出格式
输出一行n个整数,按顺序输出每个出圈人的编号。
输入输出样例
输入样例
10 3
输出样例
3 6 9 2 7 1 8 5 10 4
补充知识
使用STL来操作队列,队列的头文件是<queue>,有以下几种方法:
(1)queue<int> q:建立一个队列q,其内部元素类型是int
(2)q.push(a):将元素a插入到队列q的末尾
(3)q.pop():删除队列q的队首元素
(4)q.front():查询q的队首元素
(5)q.back():查询q的队尾元素
(6)q.size():查询q的元素个数
(7)q.empty():查询q是否为空
解析1
这个题目首先我们需要模拟一个队列,将所有的元素压进队列,在进行循环(直到队列为空为止) 时,由于队列只可以在head删除,那么这就要求我们只要这个人经过判断并且不会被剔除,那么就必须把他排在队尾;若这个人正好被剔除,那先输出他,再踢除。
#include<iostream>
#include<queue>
using namespace std;
queue<int> p;
int n,m,e=1;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
p.push(i);
}
while(!p.empty()){
if(e==m){
cout<<p.front()<<" ";
p.pop();
e=1;
}
else if(e!=m){
e++;
p.push(p.front());
p.pop();
}
}
return 0;
}
解析2
此题目也可以使用链表实现。首先将所有的同学按照顺序使用链表连接,然后从第一位同学开始数数,数到m时就把对应的元素输出,同时删除这个元素,直到链表为空为止。由于时首尾相连,所以是循环链表,只需要遍历到链表尾部,则立刻从头开始。
#include<iostream>
#include<list>
using namespace std;
list<int> a;
int main(){
int n,m,cnt=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
a.push_back(i);//将各位同学加入到链表中
}
list<int>::iterator it,now;
it=a.begin();//从头开始
while(!a.empty()){
cnt++;
now=it;//需要备份出来一个待删除元素的指针
if(++it==a.end()){
it=a.begin();//遍历下一个,循环链表
}
if(cnt==m){
cout<<*now<<' ';
a.erase(now);//删除这个结点
cnt=0;
}
}
return 0;
}