一日一码08——约瑟夫环

来源:互联网 发布:泸州2017年网络春晚 编辑:程序博客网 时间:2024/05/21 03:27
/*一日一码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;}