约瑟夫问题的四种解法

来源:互联网 发布:生活垃圾的数据 编辑:程序博客网 时间:2024/06/06 16:29

                                               约瑟夫问题的四种解法

约瑟夫问题在网上大致有三种解法:
           1、数组模拟;2,结构体模拟、3、数学递归;
     最近又发现一种解法(虽然看不懂,但还是发给大神看看,希望有人指导下):
       直接上图 :=_=!!

 

    这种解法鄙人实在不懂;
  其余解法我可以打的出来=_=:
1.数组模拟:
#includeusing 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#includetypedef 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.递归解法:
#includeusing 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
原创粉丝点击