约瑟夫问题:
设有N个人围坐在一个圆桌,现在从第S个人开始报数,数到第M个人出列,然后从出列的下一个人重新开始报数,数到第M个人又出列。。。如此反复得直到所有的人全部出列为止,Josephus问题是:对于任意给定的N,S,M,求出按出列次序得到的N个人的序列。
输入只包含一行,共三个整数,N s m 其中N表示一共有N个人,s表示从第s个人(1<=s<=N)报数,m表示从s开始数到第m个人出列。
// Josephus Problem.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
#define FALSE 0
#define TRUE 1
struct Node;
typedef struct Node* PNode;
struct Node
{
int info;
PNode link;
};
typedef struct Node* LinkList;
typedef LinkList * PLinkList;
int init_clist(PLinkList pclist,int n)
{
PNode p,q;
int i;
q=(PNode)malloc(sizeof(struct Node));
if(q==NULL)
return FALSE;
*pclist=q;
q->info=1;
q->link=q;
if(n==1)
return TRUE;
for(i=2;i<n+1;i++)
{
p=(PNode)malloc(sizeof(struct Node));
if(p==NULL)
return FALSE;
p->info=i;
p->link=q->link;
q->link=p;
q=p;
}
return TRUE;
}
void josephus_clist(PLinkList pclist,int s,int m)
{
PNode p,pre;
int i;
p=*pclist;
pre=NULL;
if(s==1)
{
pre=p;
p=p->link;
while(p!=*pclist)
{
pre=p;
p=p->link;
}
}
else
for(i=1;i<s;i++)
{
pre=p;
p=p->link;
}
while(p!=p->link)
{
for(i=1;i<m;i++)
{
pre=p;
p=p->link;
}
cout<<" "<<p->info<<" ";
if(*pclist==p)
*pclist=p->link;
pre->link=p->link;
free(p);
p=pre->link;
}
cout<<" "<<p->info<<" ";
*pclist=NULL;
free(p);
}
int _tmain(int argc, _TCHAR* argv[])
{
LinkList josList;
int n,s,m;
cin>>n;
cin>>s;
cin>>m;
if(init_clist(&josList,n))
josephus_clist(&josList,s,m);
else
cout<<"Out of Space"<<endl;
return 0;
}