約瑟夫環問題代碼示例

約瑟夫環問題

據說著名猶太曆史學家 Josephus有過以下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡爲止。然而Josephus 和他的朋友並不想遵從。首先從一個人開始,越過k-2個人(因爲第一個人已經被越過),並殺掉第k個人。接着,再越過k-1個人,並殺掉第k個人。這個過程沿着圓圈一直進行,直到最終只剩下一個人留下,這個人就可以繼續活着。問題是,給定了和,一開始要站在什麼地方纔能避免被處決?Josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。->摘自百度百科

那麼約瑟夫環是怎麼實現的呢,毋庸置疑,循環鏈表

#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
  int data;
  struct node* next;
}node;

node *create(int n)
{
 node *p=NULL,*head;
 head=(node*)malloc(sizeof(node));
 p=head;
 node *s;
 int i=1;
 if(n!=0)
 {
   while(i<=n)
   {
     s=(node*)malloc(sizeof(node));
     s->data=i++;
     p->next=s;
     p=s;
   }
   s->next=head->next;
 }
 free(head);
 return s->next;
}
int main(void)
{
 int n=41;
 int m=3;
 int i;
 node *p=create(n);
 node *temp;
 m%=n;
 while(p!=p->next)
 {
   for(i=1;i<m-1;i++)
   {
     p=p->next;
   }
   printf("%d->",p->next->data);
   temp=p->next;
   p->next=temp->next;
   free(temp);
   p=p->next;
 }
 printf("%d\n",p->data);
 return 0;
}

約瑟夫問題代碼
然後讓我們來看看相似的題
編號爲1~N的N個人按照順時針方向圍坐一圈,每人持有一個密碼(正整數,可以自由輸入),開始人選一個正整數作爲報數上限M,從第一個人按照順時針方向自1開始順序報數,報道M時停止報數,報M的人出列,將他的密碼作爲新的M值,從他順時針方向上的下一個人開始從1報數,如此下去,直至所有人全部出列爲止

以下是代碼

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

typedef struct node
{
  int num;
  int code;
  struct node *next;
}node;

node *create(int n)  //創建一個n個數據元素的循環鏈表
{
  node *p=NULL,*head;
  head=(node*)malloc(sizeof(node)); //創建一個頭節點
  p=head;          //將p指向頭節點
  if(p==NULL)    //如果頭節點創建失敗
  {
    return 0;
  }
  /*生成一組隨機數存儲密碼的值*/
  time_t ts;
  srand((unsigned int)time(&ts)); //生成隨機數種子
  node *s;
  if(n!=0)
  {
     for(int i=1;i<=n;i++)
     {
       s=(node*)malloc(sizeof(node));   //生成一個新的節點
       s->num=i;         //每個節點編號
       s->code=rand()%11+1;     //隨機生成每個人的密碼
       p->next=s;      //第一次使頭節點指向s,之後使上一個數據元素指向節點s
       p=s;          //使p的位置後移
     }
     s->next=head->next;
     free(head);
  }
  return s->next;
}
int main(void)
{
  int n;
  int m;
  printf("\n--------------------------------------\n");
  printf("        請輸入有幾個人參加遊戲:         \n");
  scanf("%d",&n);
  node *p=create(n);     //生成一個循環鏈表
  node *temp;              //聲明一個臨時變量作爲交換
  while(p->next!=p)
  {
    m=p->code;
    m%=n;
    for(int i=1;i<m-1;i++)
    {
      p=p->next;            //使p指向出列數據的上一個數據元素
    }
    printf("%d>>",p->next->num);    //打印出列人的編號
    temp=p->next;
    p->next=temp->next;
    free(temp);
    p=p->next;
  }
  printf("%d\n",p->num);    //打印最後一個人的編號
  return 0;
}    

下面是代碼運行情況
示範

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章