約瑟夫問題(陣列與迴圈連結串列實現)
阿新 • • 發佈:2018-12-12
約瑟夫問題
一個旅行社要從n名旅客中選出一名幸運旅客,為他提供免費環球旅行服務。方法是,大家站成圈,然後選定一個m,從第1個人開始報數,報到m時,這個人OUT,然後從下一個人開始重新從1報數,重複這個過程,直到最後剩下一個人就是幸運之星。問題就是誰是幸運者呢?
1.陣列實現 關鍵思想:
- 建立一個數組儲存旅客的的狀態,賦初值為1 , 0表示out。
- 利用i=(i+1)%n,迴圈遍歷陣列。
#include <stdio.h> #include <stdlib.h> int main() { int n,m; int i; scanf("%d %d",&n,&m);//輸入n名旅客,每m個人out。 int *flag = (int*)malloc(n*sizeof(int));//建一個一位陣列儲存n名n旅客的狀態(是否out) //陣列賦初值為1,表示沒有out for(i=0; i<n; i++){ flag[i]=1; } int count = 0;//記錄出圈人數 int mcount = 0;//記錄報數 for(i=0;i<n;i=(i+1)%n){ //i=(i+1)%n實現迴圈遍歷 if(flag[i] == 1){ mcount++; if(mcount == m){ printf("%d\n",i+1); count++; flag[i]=0; //表示out mcount=0; //報數器歸零 } if(count == n-1){ break; } } } //查詢最後剩下人的編號 for(i=0; i<n; i++){ if(flag[i] == 1){ printf("lucky tourist is %d\n",i+1); } } free(flag); return 0; }
2.迴圈連結串列實現
#include<stdio.h> #include<stdlib.h> typedef struct node{ int data; struct node *next; }LinkList; int Josephus(int n,int m); int Josephus(int n,int m){ LinkList *L,*r,*s; L = (LinkList*)malloc(sizeof(LinkList)); r=L; //尾插法建立有頭節點的迴圈連結串列 for(int i=1;i<=n;i++){ s=(LinkList*)malloc(sizeof(LinkList)); s->data = i; r->next = s; r = s; } r->next=L->next;//將尾與頭連線 LinkList *p=L->next; while(p->next!=p){ for(int i=1;i<m-1;i++){ p=p->next; } //刪除結點 p->next=p->next->next; p=p->next; } return p->data; } int main(){ int n,m; scanf("%d %d",&n,&m); printf("%d\n",Josephus(n,m)); return 0; }