约瑟夫问题:n 个人围成一圈,从第一个人开始报数,数到 m 的人出圈,从下一个人开始重新报数,... 直到圈中只剩最后一个人。用户输入两个正整数 n =总人数, m =报数人数,输出最后在圈中的人员编号。例如 n =5, m = 3,则每一次报数以后在圈中的人员为:第一次: 1 2 4 5第二次: 4 5 2第三次: 2 4第四次: 4所以应输出 3 1 5 2 4. 要求输出时,每个出圈的人员编号占4个字符宽度【样例输入】10 6【样例输出】 6 2 9 7 5 8 1 10 4 3【样例输入】8 5【样例输出】 5 2 8 7 1 4 6 3
时间: 2023-03-30 22:00:49 浏览: 126
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉 例如N=6,M=5
5星 · 资源好评率100%
我可以回答这个问题。这是约瑟夫问题,可以使用循环链表来解决。首先创建一个循环链表,每个节点表示一个人,节点编号从1到n。然后从第一个节点开始,依次报数,每报数到m,就将该节点从链表中删除。直到链表中只剩下一个节点为止,该节点即为最后在圈中的人员编号。最后按照出圈的顺序输出每个人员的编号,每个编号占4个字符宽度即可。以下是示例代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int num;
struct node *next;
} Node;
int main() {
int n, m;
scanf("%d %d", &n, &m);
// 创建循环链表
Node *head = (Node*)malloc(sizeof(Node));
head->num = 1;
Node *tail = head;
for (int i = 2; i <= n; i++) {
Node *p = (Node*)malloc(sizeof(Node));
p->num = i;
tail->next = p;
tail = p;
}
tail->next = head;
// 开始报数并删除节点
Node *p = head;
while (p->next != p) {
for (int i = 1; i < m; i++) {
p = p->next;
}
printf("%4d", p->num);
Node *q = p->next;
p->num = q->num;
p->next = q->next;
free(q);
}
printf("%4d\n", p->num);
return ;
}
阅读全文