现在的位置: 首页 > 综合 > 正文

约瑟夫环

2013年12月08日 ⁄ 综合 ⁄ 共 1445字 ⁄ 字号 评论关闭

n个人,编号1,2,。。。n,从头开始报数,报到m的人出列,然后从下一个人重新开始报数,直至到最后一个人,求最后一个人出列的时其原始的序号。

1、用链表

步骤:

1构建循环链表,数据域为序号

2遍历循环链表(p->next!=p),利用k计数,当k=m,则将m对应的结点删除掉,继续遍历

3当只剩一个结点,p->next=p,将p->num输出

#include<stdio.h>
#include<malloc.h>
typedef struct node{
 int num;
 node *next;
}node;
node *creat(int n){  //构建循环链表
 node *head,*p,*q;
 int i=1;
 p=(node*)malloc(sizeof(node));
 p->num=i;
 head=p;
 for(i=2;i<=n;i++){
  q=(node*)malloc(sizeof(node));
  q->num=i;
  p->next=q;
 p=p->next;
 }
 q->next=head;    //首尾相连
 return head;
}
node*find_last_out(node* head,int m){
 node* s,*p,*q;
 int k=1;   //计数
    p=head;
 while(p->next!=p){  //遍历至只剩一个结点
  while(k!=m){  //m表示要数到的数
   q=p;
   p=p->next;
   k++;
  }
  if(k==m){
   k=1;
   s=p;
   q->next=p->next;
   p=p->next;
   printf("s->num: %d\n",s->num);
   free(s);
  }
 }
 if(p->next=p){
  printf("%d",p->num);
 }
 return p;

}
void main(){
node* head;
head=creat(7);
head=find_last_out(head,3);
printf("head->num: ",head->num);
}

2.非递归方法:

#include<stdio.h>
#include<assert.h>
void main(){
 int m,n;
 int i;
 scanf("%d,%d",&n,&m);
 assert(m&&n);
 int r=0;
 for(i=2;i<=n;i++){
  r=(r+m)%i;
 }
 printf("%d",r+1);
 }

3.递归式

#include<stdio.h>
int find_last_out(int n,int m){
 if(n==1)
  return 0;
 else
  return ((m+find_last_out(n-1,m))%n);
}
void main()
{
 int m,n;
 int res;
 scanf("%d,%d",&n,&m);
 res=find_last_out(n,m)+1;
 printf("%d\n",res);
}

参考:http://www.cnblogs.com/cnyao/archive/2009/10/31/Question1.html

           

http://blog.csdn.net/a725sasa/article/details/11664375

           

http://blog.csdn.net/a725sasa/article/details/11664375

 

 

抱歉!评论已关闭.