题目描述
描述
约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
输入
8 1 3 (n=8 k=1 m=3 )
输出
7 (剩下的那个)
分析
删除位置的计算
从线性表中起始位置index出发开始计数,当计数到k时(间隔k-1个数据),删除该位置上的元素;同时该位置又是下一次计数的起始位置:
index=(index+k-1)%顺序表的长度
顺序表解决
算法:
1.创建一个长度为n的顺序表
2.从第index(初值0)个元素出发,依次计数,每数到d,就将该元素删除
3.index=(index+d-1)%顺序表的长度
重复上述工作,直到顺序表中只剩一个元素
#include <iostream.h> //引用输入输出流库函数的头文件
#include "SeqList.cpp" //引用顺序表类SeqList
void main(){
int n=5, i=0;
char b[]={‘A’,‘B’,‘C’,‘D’,‘E’}; //可以通过键盘输入,从而动态的确定数组的长度
SeqList<char>a(b,5);
int start=1,d=2; //可以通过键盘输入任意的数字
int index = start-1; //计数起始位置,对应数组下标
while (a.Length()>1) {
index = (index+d-1) % a.Length();
cout<<"删除"<<a.Delete(index+1)<<endl;
}
cout<<a.Get(1))<<endl;
}
循环链表解决
#include<iostream>
using namespace std;
struct Node
{
int data;Node*pNext;
};
int main(){
int i,n,k,m;
struct Node *p,*q,*first;
cin>>n>>k>>m;
if(m==1)
{
int left;
left=k-1;
if(left==0)
left=n;
cout<<left;
return 0;
}
first=(Node*)new Node;
p=first;
first->data=1;
for(i=2;i<=n;i++)
{
q=new Node;
q->data=i;
p->pNext=q;
p=p->pNext;
}
p->pNext=first;
p=first;
for(i=1;i<=k-1;i++)
{
p=p->pNext;
}
while(p!=p->pNext)
{
for(i=1;i<m-1;i++)
{
p=p->pNext;
}
q=p->pNext;
p->pNext=q->pNext;
delete q;
p=p->pNext;
}
cout<<p->data<<endl;
return 0;
}