/*一日一码08:约瑟夫环问题 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。 从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列。 求最后出列那个人的编号。 */ #include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node *next; } node; void listMethod(int n, int k, int m){ int i = 0,step = m; node *head,*p,*q; p = NULL; //建立循环队列 head = (node*)malloc(sizeof(node)); q = head; for (i = 1; i <= n; i++) { p = (node*)malloc(sizeof(node)); p->data = i; q->next = p; q = q->next; } p->next = head->next; //报数 p = head->next; while (p->next != NULL && p->next != p) { printf("%d号报数!\n", p->data); step--; if (step == 0) { //出列 printf("本次%d号出局!\n", p->data); p->data = p->next->data; q = p->next; p->next = p->next->next; free(q);//曾写成free(p->next),这样链表就断啦! step = m; }else { p = p->next; } } printf("最后剩下%d号!\n", p->data); } int next(int arr[],int size,int start, int step, int flag){ int i = 0; for ( i = start; step > 0; step--) { if(flag){ printf("%d号报数!\n", i+1); } while(-1 == arr[(i + 1)%size]){ i = (i + 1)%size; } i = (i + 1)%size; } return i; } //数组法实现 int arrayMethod(int n, int k, int m){ int i = 0; int left = n; int *arr = (int*)malloc(sizeof(int)*n); //初始化 for (i = 0; i < n; ++i) { arr[i] = i+1; } //i用来表示下一个人 i = 0; k = k - 1; //开始报数 while( left > 1){ i = next(arr,n,k,m-1,1); arr[i] = -1; //打印每次出局的人 printf("%d号报数!\n本次%d号出局!\n", i+1,i+1); k = next(arr,n,i,1,0); left--; } i = next(arr,n,k,1,0); printf("最后剩下%d号!\n", i+1); return k; } int main(int argc, char const *argv[]) { int n,k,m; n = 9; k = 1; m = 5; arrayMethod(n,k,m); listMethod(n,k,m); return 0; }
一日一码08——约瑟夫环
最新推荐文章于 2021-03-23 18:08:00 发布