如果对n-1个人,最后出列人的编号为k=f (n-1);则对n个人,第一个报m数的人出列后,重排列
.当m % n = 0时,为1, ..., n-1
–则 f(n) = k
.否则,为m%n+1, ..., n, 1, m%n-1
–如果 k ≤ n-m%n则,f(n) = m%n+k
–如果 k > n-m%n则,f(n) = k - n + m%n
.当m % n = 0时,为1, ..., n-1
–则 f(n) = k
.否则,为m%n+1, ..., n, 1, m%n-1
–如果 k ≤ n-m%n则,f(n) = m%n+k
–如果 k > n-m%n则,f(n) = k - n + m%n
.T(n)=T(n-1)+ Θ(1) = Θ(n)
归纳假设:假设知道n个人,最后一个的出队列的人,不妨为f(n)
证明:基础条件,对于n=1 的时候,报数到m的肯定为自身
假设f(n-1)是前1,2,.......n-1中最后出队列的人。
如果m%n==0 第一出来的就是n,还剩余1.,2.......n-1 则 f(n)=f(n-1)
如果m%n!=0
则
m%n+1-------->1
m%n+2-------->2
....
n----------->n-m%n
1----------->n-m%n+1
2---------->n-m%n+2
....
m%n-1---->n-1
左侧为真实值,右侧为从新报数的值
看到如果 k=f(n-1)
if(k<=n-m%n) 真实值为f(n)=k+m%n
else 真实值为f(n)=k-(n-m%n)
// 约瑟夫问题.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
/*author:surpassgood
约瑟夫问题:假设有n个,第一次报数到m的人出列,下个元素从1开始报数
知道所有的人的出列为止
*/
#define N 5//N 为总人数
#define M 2//报到M的人出列
int fun(int n)//假设n个人 最后出列的那个人
{
if(n==1) return 1;
if(M%n==0) return fun(n-1);
else
{
int k=fun(n-1);
if(k<=(n-(M%n)))
{
return k+(M%n);
}
else
return k-(n-M%n);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
cout<<fun(N)<<endl;
return 0;
}
用循环链表的代码,如下
typedef struct node
{
int data;
node * next;
}node;
void create_link(node * &head,node * &tail,int n)
{
if(n<1)
return;
head=new node();
head->data=1;
head->next=NULL;
int i;
node *p;
node *pre=head;
for(i=2;i<n+1;i++)
{
p=new node();
p->data=i;
p->next=NULL;
pre->next=p;
pre=p;
}
tail=p;
tail->next=head;
}
void look_m(node* &head,node * &tail,int m)
{
node *pre,*cur;
pre=tail;
cur=head;
int number=0;
int delete_number=0;
while(cur&&cur->next!=cur)
{
++number;
if(number==m)
{
cout<<" "<<cur->data;
pre->next=cur->next;
delete cur;
cur=pre->next;
number=0;
}else
{
pre=cur;
cur=cur->next;
}
}
if(cur)
{
cout<<" "<<cur->data;
delete cur;
head=NULL;
tail=NULL;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
node *head,*tail;
create_link(head,tail,9);
look_m(head,tail,5);
return 0;
}
附上循环链表的代码
NODE * create2(int n)//建循环链表
{
NODE *head=new NODE;
head->elem=1;
head->next=head;
NODE *cur=head;
int i;
for(i=2;i<=n;i++)
{
NODE *s=new NODE;
s->elem=i;
s->next=cur->next;
cur->next=s;
cur=s;
}
return head;
}
void prin(NODE *head)//打印元素
{
NODE *p=head;
while(p->next!=head){
cout<<p->elem<<" ";
p=p->next;
}
cout<<p->elem<<endl;
}
void report(NODE *head,int n,int m)//从n中报到m的删除
{
NODE *p=head;
NODE *r=head;
while(r->next!=head)
{
r=r->next;
}
while(n--)
{
for(int s=m-1;s--;r=p,p=p->next);
r->next=p->next;
cout<<" "<<p->elem<<endl;
delete p;
p=r->next;
}
}