约瑟夫环问题:实现所有出列的人形成新队列并输出游戏多次后的队列顺序
约瑟夫环问题:实现所有出列的人形成新队列并输出游戏多次后的队列顺序
问题描述
有 n 个人围成一个圆圈,从第 1 个人开始报数,报到 m 的人出局,然后从下一个开始报数,继续报到 m 的人出局,以此类推,直到剩下最后一个人。
本题要求实现以下功能:
- 实现约瑟夫环问题,输出每次游戏出列的人的编号。
- 实现多次游戏,每次使用不同的报数密码,并输出每次游戏结束后队列的顺序。
代码实现
#include <iostream>
#include <vector>
using namespace std;
typedef struct Lnode{
int data;
struct Lnode *next;
}LNode,*Linklist;
void creatlist(Linklist &head, int n){
head = new LNode;
head->next = NULL;
LNode *r = head;
for(int i = 1; i <= n; i++){
LNode *p = new LNode;
p->data = i;
p->next = NULL;
r->next = p;
r = p;
}
r->next = head->next;
}
void josephus(Linklist &head, int n, int m){
LNode *p = head->next;
LNode *q;
int num = 0;
while(num < n){
for(int i = 1; i < m; i++){
q = p;
p = p->next;
}
cout << p->data << ' '; //输出
q->next = p->next;
delete p;
p = q->next;
num++;
}
}
int main(){
int n, m;
cout << "请输入玩游戏的人数M,回车输入:";
cin >> n;
Linklist head = NULL;
creatlist(head, n);
int numPasswords;
cout << "请输入每遍游戏的报数密码个数,回车输入:";
cin >> numPasswords;
vector<int> passwords(numPasswords);
cout << "请输入每遍游戏的报数密码,回车输入:";
for(int i = 0; i < numPasswords; i++){
cin >> passwords[i];
}
Linklist backupHead = NULL;
creatlist(backupHead, n);
for(int i = 0; i < numPasswords; i++){
cout << "第 ' << i+1 << " 遍游戏完成后队列次序:";
josephus(head, n, passwords[i]);
cout << endl;
head = backupHead; // 恢复原始队列
}
return 0;
}
代码解释
- 使用循环链表来模拟约瑟夫环。
creatlist函数用来创建循环链表。josephus函数用来模拟游戏过程,输出每次出列的人的编号。- 在
main函数中,首先输入玩游戏的人数和报数密码个数,然后输入每个报数密码。 - 每次游戏开始前,复制原始队列作为备份队列,并在游戏结束后恢复原始队列。
- 使用循环遍历每个报数密码,进行游戏并输出每次游戏后的队列顺序。
使用方法
- 将代码保存为
.cpp文件。 - 使用 C++ 编译器编译代码。
- 运行编译后的可执行文件。
示例
输入:
5
2
3
5
输出:
第 1 遍游戏完成后队列次序:3 1 5 2 4
第 2 遍游戏完成后队列次序:5 4 1 3 2
总结
本代码实现了约瑟夫环问题的多种游戏,并输出每次游戏后的队列顺序。可以使用循环链表来模拟约瑟夫环,并使用 delete 操作来模拟出列。通过备份队列,可以实现多次游戏的操作。
原文地址: https://www.cveoy.top/t/topic/RuN 著作权归作者所有。请勿转载和采集!