具體的數學實現方法就不寫了,網上有大把大把的
這里寫兩種最容易理解的版本
第一種是最簡單的鏈表實現方法
#include<stdio.h> #include<stdlib.h> /* 第一種是鏈表法 首先創建一個循環單鏈表 將每一個參加該游戲的人設定為一個節點 每個節點的data域代表了每個人的編號 總共有n個人參加游戲 當輪流報數到m的時候,該玩家出局 out order代表了每個人的報數情況 在刪除節點方面,我選用帶頭節點循環單鏈表 引入兩個指針pre和q,當pre是q的前節點 每一次需要刪除q時,只需要動用pre即可 由於是兩個節點,所以當鏈表中只剩一個節點 即p==q的時候,就是停止循環的條件 */ typedef struct node{ int data; struct node *next; }Node,*pointer; int main(){ int m=3; int n=41; pointer head=(pointer)malloc(sizeof(Node)); pointer tail=head; head->next=NULL; int number=1; while(number<=n) { pointer s=(pointer)malloc(sizeof(Node)); s->data=number++; tail->next=s; tail=s; } tail->next=head->next; pointer pre=tail; pointer q=head->next; int order=1; while(pre!=q) { if(order==m) { printf("out of the game %d\n",q->data); pre->next=q->next; free(q); q=pre->next; order=1; } else { pre=q; q=q->next; order++; } } printf("\n the winner is %d\t",pre->data); }
第二種是數組成環實現
/* 設定一個參賽者數組,數組的名字為gamer n,m設定與上面的鏈表設定一樣 number代表參賽者的人數 pos代表當前報數者的位置 當報數者的報數為3時,將其out,然后其數組置為0 為了使數組形成環,就需要用到隊列中學到的知識 使用pos=(pos+1)%n 當pos==n-1的時候(數組的最后一位) pos+1會變到的數組的第一位,從而形成閉環 */ int main() { int m=3,n=41;//m是出局編號,n是參賽者人數 int number=n; int pos=0; int order=1; int gamer[41]; for(int i=0;i<41;i++) gamer[i]=i+1; while(number>1) { if(gamer[pos]!=0)//當報數者沒有出局的時候,也就是其數組沒有被置為0 { if(order==m)//如果被order為3了,將其數值置為0 { printf("gamer %d out\n",gamer[pos]); gamer[pos]=0; pos=(pos+1)%n; number--; order=1; } else { ++order; pos=(pos+1)%n; } } else//如果數值為0,則跳過當前元素 pos=(pos+1)%n; } for(int i=0;i<41;i++) if(gamer[i]!=0) printf("winner is %d\n",gamer[i]); }