1、项目简介:
约瑟夫生者死者游戏的大意是:30个旅客同乘一条船,因为严重超载,加上风高浪大危险万分;因此船长告诉乘客,只有将全船一半的旅客投入海中,其余人才能幸免于难。无奈,大家只得同意这种方法,并议定30个人围成一圈,由第一个人开始,依次报数,数到第9人,便将他投入大海中,然后从他的下一个人数起,数到第9人,再将他投入大海,如此循环,直到剩下15个乘客为止。问哪些位置是将被扔下大海的位置。
2、项目功能要求:
本游戏的数学建模如下:假如N个旅客排成一个环形,依次顺序编号1, 2, …, N。从某个指定的第S号开始。沿环计数,每数到第M个人就让其出列,且从下一个人开始重新计数,继续进行下去。这个过程一直进行到剩下K个旅客为止。
使用单循环链表来存储旅客的位置信息,然后在for循环内找到死亡旅客的位置,找到该位置后将前一个位置的next指针连接到下一个位置上,相当于删除了该死亡旅客的位置,并将其信息打印出来,之后总人数减一。逐步寻找并删除,直至总人数等于幸存者人数,然后按位置的大小顺序排序后打印出幸存者位置。
#include <iostream>
using namespace std;
#include <cstring>
#include <stdlib.h>
#include <malloc.h>
#include"Stack.h"
/*----玩家结构体----*/
struct Player {
int pos; //玩家所处初始位置
struct Player* Next; //尾指针
};
/*----核心函数----*/
Player* solve(int n, int s, int m, int k) {
Player* p; //临时指针
Player* Josephus = new Player[n]; //创建约瑟夫循环链表
int count = 1; //计数器
//约瑟夫环的初始化
for (int i = 0; i < n; i++) {
Josephus[i].pos = i + 1;
if (i != n - 1)
Josephus[i].Next = &Josephus[i + 1];
else
Josephus[i].Next = &Josephus[0];
}
//寻找第一个位置,对s = 1进行特殊处理
s--;
if (s - 1 >= 0)
p = &Josephus[s - 1];
else
p = &Josephus[n - 1];
//将死者删除出链表,累加位置,直到达到人数要求
while (n > k) {
for (int i = 0; i < m - 1; i++)
p = p->Next;
cout << "第" << count << "个死者的位置是: " << p->Next->pos << endl;
n--;
count++;
p->Next = p->Next->Next;
}
//为达到从小到大输出,移动指针
while (p->pos < p->Next->pos)
p = p->Next;
p = p->Next;
return p;
}
//单循环链表实现
int main()
{//为了让游戏更加具有普适性,定义为:现有N人围成一圈,
//从第S个人开始依次报数,报M的人出局,再由下一个人
// 开始报数,如此循环,直到剩下K个人为止。
//显然,十分具有普适性了。
int N, S, M, K;
Player *p; //循环指针
cout << "为了让游戏更加具有普适性,定义为:现有N人围成一圈,"
<< "从第S个人开始依次报数,报M的人出局," << endl;
cout << "再由下一个人开始报数,如此循环,直到剩下K个人为止。"
<< "显然,十分具有普适性了" << endl;
cout << "请输入生死游戏的总人数N:";
cin >> N;
//容错操作
while(N < 2)
{
cout << "至少需要两个人!请重新输入:";
cin >> N;
}
cout << "请输入游戏开始的位置S:";
cin >> S;
//容错操作
while (S > N)
{
cout << "错误的位置,请重新输入:";
cin >> S;
}
cout << "请输入死亡数字M:";
cin >> M;
//容错操作
while (M <=0)
{
cout << "死亡数字应为正整数,请重新输入:";
cin >> M;
}
cout << "请输入剩余的生者人数K:";
cin >> K;
//容错操作
while (K < 0 && K > N)
{
cout << "剩余的生者人数应为正整数且应大于总人数,请重新输入:";
cin >> K;
}
//调用核心函数
p = solve(N, S, M, K);
//输出
cout << "最后剩下: " << K << "人" << endl;
cout << "剩余的生者位置为: ";
for (int i = 0; i < K; i++)
{
cout << p->pos << " ";
p = p->Next;
}
cout << endl;
cout << "20213002624李季鸿" << endl;
system("pause");
return 0;
}