约瑟夫问题的四种解法
约瑟夫问题在网上大致有三种解法:
1、数组模拟;2,结构体模拟、3、数学递归;
最近又发现一种解法(虽然看不懂,但还是发给大神看看,希望有人指导下):
直接上图 :=_=!!
这种解法鄙人实在不懂;
其余解法我可以打的出来=_=:
1.数组模拟:
#include
using namespace std;
int main()
{
int m,k,livenum,count=0;
scanf("%d%d",&m,&k);
int *p=new int[m+1];
for(int i=1;i<=m;i++)
{
p[i]=i+1;
}
p[m]=1;
for(i=1,livenum=m;livenum!=1;i=p[i])
{
count++;
if(count==k-1)
{
printf("%d\n",p[i]);
p[i]=p[p[i]];
livenum--;
count=0;
}
}
printf("Win=%d\n",p[i]);
delete []p ;
return 0;
}
2.结构体模拟:
#include
#include
typedef struct List{
int r;
struct List* next;
}L;
void main()
{
L *head,*s,*a;
int k,m,livenum,count=0;
scanf("%d%d",&m,&k);
head=(L*)malloc(sizeof(L));
a=head;
a->r=1;
for(int i=2;i<=m;i++)
{
s=(L*)malloc(sizeof(L));
s->r=i;
a->next=s;
a=s;
}
s->next=head;
livenum=m;
a=head;
while(livenum!=1)
{
if(a->r==0)
{
a=a->next;
continue;
}
else
{
count++;
if(count==k)
{
count=0;
a->r=0;
livenum--;
}
}
a=a->next;
}
while(a->r==0)
a=a->next;
printf("%d\n",a->r);
return ;
}
3.递归解法:
#include
using namespace std;
void main()
{
int m,k,ans;
cin>>m>>k;
ans=0;
for(int i=2;i<=m;i++)
ans=(ans+k)%i;// 从两只猴子开始迭代
cout<
<
为了简化问题,把首个猴子的编号编为0,第M个猴子的编号为m-1,假设k个人踢出,
排列为 0 1 2 。。。k-2 k。。。。 。。m-2 m-1;
重新排列为一个新的约瑟夫环 k k+1 k+3 。。。m-2 m-1 0 1 2 3。。。k-2
( 0 1 2 k-2 k-1 k 。。。。。m-3 m-2)
重新排列的环就是M个人数的子问题,只要把该子问题解决就可以得到M人数的问题解;而求该子问题的解,还须求(M-2)的人数解······由此只要知道人数为一时的解即可递归出M人数的解;
那么其中的解关系是什么?
由上排序组知:X(M)=(X(M-1) +k)%M;
这位大佬的博文也不错哦
http://blog.csdn.net/qq_25973267/article/details/50405616