C语言编写代码约瑟夫生者死者小游戏30 个人在一条船上,超载,需要 15 人下船。于是人们排成一队,排队的位置即为他们的编号。报数,从 1 开始,数到 9 的人下船。如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?
时间: 2024-03-22 14:42:00 浏览: 13
好的,这是一个经典的约瑟夫问题,可以用循环链表来解决。下面是使用C语言编写的解决方案:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int num;
struct node *next;
} Node;
// 创建循环链表,返回头结点指针
Node *createList(int n) {
Node *head = (Node *)malloc(sizeof(Node));
Node *tail = head;
head->num = 1;
for (int i = 2; i <= n; i++) {
Node *p = (Node *)malloc(sizeof(Node));
p->num = i;
tail->next = p;
tail = p;
}
tail->next = head;
return head;
}
// 释放链表内存
void freeList(Node *head) {
Node *p = head->next;
while (p != head) {
Node *temp = p;
p = p->next;
free(temp);
}
free(head);
}
// 模拟约瑟夫过程,返回下船的人的编号
int *josephus(int n, int m, int k) {
Node *head = createList(n);
Node *tail = head;
while (tail->next != head) {
tail = tail->next;
}
int *res = (int *)malloc(k * sizeof(int));
int count = 0;
while (tail != head) {
for (int i = 1; i < m; i++) {
tail = head;
head = head->next;
}
res[count++] = head->num;
tail->next = head->next;
Node *temp = head;
head = head->next;
free(temp);
}
res[count++] = head->num;
// 只输出最后下船的15个人的编号
int *result = (int *)malloc(k * sizeof(int));
for (int i = 0; i < k; i++) {
result[i] = res[i + n - k];
}
freeList(head);
free(res);
return result;
}
int main() {
int n = 30; // 总人数
int m = 9; // 报到9的人下船
int k = 15; // 最后只剩15人
int *res = josephus(n, m, k);
printf("下船的人的编号为:");
for (int i = 0; i < k; i++) {
printf("%d ", res[i]);
}
printf("\n");
free(res);
return 0;
}
```
上面的代码中,我们先创建了一个循环链表,然后模拟约瑟夫过程,每次从链表中删除第m个节点,直到只剩下15个节点为止,最后输出下船的人的编号。