//一堆猴子都有编号,编号是1,2,3 …m,这群猴子(m个)按照1-m的顺序围坐一圈,从第f开始数,每数到第N个,该猴子就要离开此圈,这样依次下来,直到圈中剩下最后一只猴子,则该猴子为大王。
#include <stdio.h>
#include <stdlib.h>
typedef struct monkey {
int num;
struct monkey * next;
} monkey_t;
monkey_t *head = NULL, *tail = NULL;//head指向第一个节点,tail指向最后一个节点
void create(int nn) { //猴子的个数
int i;
monkey_t *p = NULL, *q = NULL; //定义两个结构体指针p和q,p指向一个新分配的节点,q指向当前最后一个节点
p = (monkey_t *)malloc(sizeof (monkey_t));//分配空间 sizeof(monkey_t)计算monkey_t所需要分配的空间大小
p->num = 1;
p->next = NULL;
head = p;
q = p;
for (i = 2; i <= nn; i++) {
p = (monkey_t *)malloc(sizeof (monkey_t));
p->num = i;
p->next = NULL;
q->next = p;
q = p;
}
tail = q;
tail->next = head; //形成闭环,建立循环链表
}
int select(int mm,int first) {
int x = 0, res;
monkey_t *p = NULL, *q = NULL; //p指向当前要判断的节点,q跟随在p的后面,比p慢一拍
q = tail;
while(first!=1) {
q=q->next;
first--;
}
do {
p = q->next; //定位p
x++;
if (x % mm == 0) {
// printf("The deleted monkey's number is No.%d\n", p->num);
q->next = p->next;
free(p);
//p = NULL;
} else {
q = p; //q跟进一步
}
} while (q != q->next); //循环直到只剩下一个节点
//head = q;
res = q->num;
free(q);
return res;
}
int main() {
int m, n,f;
printf("请输入一共有多少个猴子 \n");
scanf("%d", &m);
printf("输入一个数,数到这个数的猴子就要离开此圈 \n");
scanf("%d", &n);
printf("请输入从第几个猴子开始 \n");
scanf("%d", &f);
if(n==1&f==1){
system("cls");
printf("\n ☆ 猴子大王是 %d 号 ☆\n", m);
return 0;
}
else{
create(m);
system("cls");
printf("\n ☆ 猴子大王是 %d 号 ☆\n ", select(n,f));
return 0;
}
}