![](https://i-blog.csdnimg.cn/blog_migrate/87c22cf5449985f559452f9bf1f3aac2.png)
一、队列
#include <stdio.h>
#include <queue>
using namespace std;
queue<int> q;
int n, m, cnt, out, a[101]; //a[i]=0表示在圈里
int main()
{
scanf("%d %d", &n, &m);
for(int i=1; i<=n; i++){
q.push(i);
}
while(!q.empty()){
cnt++;
if(cnt==m){
cnt=0;
printf("%d ", q.front());
q.pop();
}
else{
q.push(q.front());
q.pop();
}
}
return 0;
}
二、循环队列思路
#include <stdio.h>
int n, m, cnt, out, a[101]; //a[i]=0表示在圈里
int main()
{
scanf("%d %d", &n, &m);
for(int i=1; ; i++){
if(i>n){
//i=i%n;
i=i-n;
}
if(a[i]==0){
cnt++;
}
if(cnt==m){
cnt=0;
out++;
printf("%d ",i);
a[i]=1;
if(out==n){
return 0;
}
}
}
return 0;
}
三、死循环
#include <stdio.h>
int n, m, cnt, out, a[101]; //a[i]=0表示在圈里
int main()
{
scanf("%d %d", &n, &m);
while(1){
for(int i=1; i<=n; i++){
if(a[i]==0){
cnt++;
}
if(cnt==m){
cnt=0;
out++;
printf("%d ",i);
a[i]=1;
if(out==n){
return 0;
}
}
}
}
return 0;
}
四、list
#include <bits/stdc++.h>
using namespace std;
int n, m;
list<int> l;
list<int>::iterator asd, temp;
int main()
{
scanf("%d %d", &n, &m);
for(int i=1; i<=n; ++i){
l.push_back(i);
}
asd=l.begin();
//当链表不为空时
while(!l.empty()){
for(int i=1; i<=m; ++i){
asd++;
//如果链表已经遍历完了, 要跳到链表开头
if(asd==l.end()){
asd=l.begin();
}
}
//数完m个之后, asd其实是在第m+1个位置的
if(asd==l.begin()){ //当第m+1个位置是表头时, 第m个位置是表尾
printf("%d ", l.back());
l.remove(l.back());
}
else{ //否则, 直接--即可
temp=asd;
--temp;
printf("%d ", *temp);
l.remove(*temp);
}
}
return 0;
}