问题描述:
已知 m 个人(分别用编号 1, 2, ..., m 表示)按顺序围成一个圈。从编号为 1 的人开始报数,数到 n 的那个人出局,他的下一个人又从 1 开始报数,数到 n 的那个人又出局,依次规律重复下去,直到全部出局,将出局的人依次显示出来。
设计思路:
因为总是从小到大报数,符合编号排序,所以用队列按顺序存储这m个人,按照先进先出原则,报到数的结点出队(无论是不是报到n的那个人),紧接着如果该结点不是数到的第n个结点,就立马在队尾处加上。
#include<bits/stdc++.h>
#include<sstream>
using namespace std;
struct node{
string name;
int id;
};
queue<node> Q;
string NumberToString(int x){
stringstream ss;
ss<<x;
return ss.str();
}
int main(){
//约瑟夫环问题
int m,n,sign=1;
cout<<"输入:人数m和出队序号n"<<endl;
cin>>m>>n;
//初始化队列
for(int i=1;i<=m;i++)
{
string num = NumberToString(i);
string str = "号";
string name = "路人";
name = num + str + name;
Q.push((node){name,i});
}
cout<<"输出:"<<endl;
while(!Q.empty())
{
if(sign == n)//当报到的数为n时,出局
{
node u = Q.front();
Q.pop();
sign = 1;
cout<<u.name<<" "<<u.id<<endl;
}
else//当报到的数不是n时,将该队头结点放到队尾
{
Q.push(Q.front());
Q.pop();
sign++;
}
}
return 0;
}