问题描述及代码:
/*现有N位旅客同乘一条船,遇到风暴只有k名乘客可以幸存,无奈大家只能进行生死游戏,
N位旅客围城一圈,从第S个人开始依次报数,顺时针报M的人出局,再由下一个人开始报
数,逆时针数到第W人出局。在从他逆时针的下一个人数起,顺时针数M人.如此循环,直
到剩下K个乘客为止*/
1.cpp:
#include<iostream>
#include"1.h"
using namespace std;
/*******************
Node类的构造函数,初始化结点数据
********************/
Node::Node()
{
data=0;
prior=NULL;
next=NULL;
}
/**************
Linklist类的构造函数,初始化首节点数据
*****************/
Doublelist::Doublelist()
{
Head=NULL;
}
/*********************
建立双向循环链表
************************/
void Doublelist::Creatlist(Doublelist &L)
{
cout<<"请输入双向生死游戏的总人数N:";
int n;
cin>>n;
Node *p,*s;
for(int i=1;i<=n;i++)
{
p=new Node;
p->data=i;
p->next=NULL;
if(i==1)
{
L.Head=p;
p->prior=NULL;
s=L.Head;
}
else
{
s->next=p;
p->prior=s;
s=s->next;
}
}
p->next=L.Head;
L.Head->prior=p;
}
/******************
获取双向循环链表的长度
********************/
int Doublelist::getLength(Doublelist &L)
{
Node *p=L.Head;
int count=0;
while(p->next!=L.Head)
{
count++;
p=p->next;
}
count++;
return count;
}
/****************************
实现约瑟夫双向生死游戏
**************************/
void DoubleJoseph()
{
Doublelist L;
L.Creatlist(L);
cout<<"请输入游戏开始的位置S:";
int s;
cin>>s;
cout<<"请输入正向的死亡数字M:";
int m;
cin>>m;
cout<<"请输入逆向的死亡数字W:";
int w;
cin>>w;
cout<<"请输入剩余的生者人数K:";
int k;
cin>>k;
cout<<endl;
Node *p,*q,*r;
p=L.Head;
for(int i=0;i<s-1;i++) //寻找S结点
{
p=p->next;
}
int t=1;
while(k<L.getLength(L))
{
if(t%2==1) //选择游戏方向 (顺时针方向)
{
for(int j=0;j<m-1;j++) //报数 找出M结点
{
q=p;
p=p->next;
}
if(p==L.Head) //元素出列
{
r=p;
L.Head=p->next;
q->next=p->next;
p->next->prior=q;
p=p->next;
}
else
{
r=p;
q->next=p->next;
p->next->prior=q;
p=p->next;
}
cout<<"第"<<t<<"个死者的位置是:"<<'\t'<<r->data<<endl;
t++;
}
else //(逆时针方向)
{
for(int j=0;j<w-1;j++) //报数 找出M结点
{
q=p;
p=p->prior;
}
if(p==L.Head) //元素出列
{
r=p;
L.Head=p->prior;
q->prior=p->prior;
p->prior->next=q;
p=p->next;
}
else
{
r=p;
q->prior=p->prior;
p->prior->next=q;
p=p->prior;
}
cout<<"第"<<t<<"个死者的位置是:"<<'\t'<<r->data<<endl;
t++;
}
}
cout<<endl<<"最后剩下"<<'\t'<<L.getLength(L)<<"人"<<endl;
cout<<"剩余的生者位置为:"<<'\t';
p=L.Head;
while(p->next!=L.Head)
{
cout<<p->data<<'\t';
p=p->next;
}
if(p)
cout<<p->data<<'\t';
cout<<endl;
}
void main()
{
cout<<"现有N位旅客同乘一条船,遇到风暴只有k名乘客可以幸存,无奈大家只能进行生死游戏,";
cout<<"N位旅客围城一圈,从第S个人开始依次报数,顺时针报M的人出局,再由下一个人开始,";;
cout<<"逆时针报数到第W人出局。在从他逆时针的下一个人数起,顺时针数M人.";;
cout<<"如此循环,直到剩下K个乘客为止."<<endl<<endl;
DoubleJoseph();
}
1.h
/* 双向循环链表的结点类 */
class Node
{
friend class Doublelist;
friend void DoubleJoseph();
public:
Node();
int data;
Node *prior;
Node *next;
};
/* 双向循环链表类 */
class Doublelist
{
friend void DoubleJoseph();
public:
Doublelist();
void Creatlist(Doublelist &L);
int getLength(Doublelist &L);
private:
Node *Head;
};
运行结果: