ZT
文章作者:Slyar 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作
题目描述:n只猴子要选大王,选举方法如下:所有猴子按 1,2 ……… n 编号并按照顺序围成一圈,从第 k 个猴子起,由1开始报数,报到m时,该猴子就跳出圈外,下一只猴子再次由1开始报数,如此循环,直到圈内剩下一只猴子时,这只猴子就是大王。
输入数据:猴子总数n,起始报数的猴子编号k,出局数字m
输出数据:猴子的出队序列和猴子大王的编号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | /* 约瑟夫问题(猴子选大王) 循环链表C语言实现 Slyar 2009.3.31 http://www.slyar.com */ #include <stdio.h> #include <stdlib.h> /* 定义链表节点类型 */ typedef struct node { int data; struct node *next; }linklist; int main() { int i, n, k, m, total; linklist *head, *p, *s, *q; /* 读入问题条件 */ printf("请输入猴子的个数:"); scanf("%d", &n); printf("请输入要从第几个猴子开始报数:"); scanf("%d", &k); printf("请输入出局数字:"); scanf("%d", &m); /* 创建循环链表,头节点也存信息 */ head = (linklist*) malloc(sizeof(linklist)); p = head; p->data = 1; p->next = p; /* 初始化循环链表 */ for (i = 2; i <= n; i++) { s = (linklist*) malloc(sizeof(linklist)); s->data = i; s->next = p->next; p->next = s; p = p->next; } /* 找到第 k 个节点 */ p = head; for (i = 1; i < k; i++) { p = p->next; } /* 保存节点总数 */ total = n; printf("/n出局序列为:"); q = head; /* 只剩一个节点时停止循环 */ while (total != 1) { /* 报数过程,p指向要删除的节点 */ for (i = 1; i < m; i++) { p = p->next; } /* 打印要删除的节点序号 */ printf("[%d] ", p->data); /* q 指向 p 节点的前驱 */ while (q->next != p) { q = q->next; } /* 删除 p 节点 */ q->next = p->next; /* 保存被删除节点指针 */ s = p; /* p 指向被删除节点的后继 */ p = p->next; /* 释放被删除的节点 */ free(s); /* 节点个数减一 */ total--; } /* 打印最后剩下的节点序号 */ printf("/n/n猴子大王为第 [%d] 号/n/n", p->data); free(p); //system("pause"); return 0; } |