据说著名犹太历史学家 Josephus 有过以下故事:在罗马人占领乔塔帕特后,39 个犹太人与 Josephus 及他的朋友躲到一个洞中,39 个犹太人决定宁愿死也不要被敌人抓到,于是决定了一种自杀方式,41 个人排成一个圆圈,由第 1 个人开始报数,报数到 3 的人就自杀,然后再由下一个人重新报 1,报数到 3 的人再自杀,这样依次下去,直到剩下最后一个人时,那个人可以自由选择自己的命运。这就是著名的约瑟夫问题。现在请用单向环形链表得出最终存活的人的编号。
一行两个整数 n 和 m, n 表示环形链表的长度, m 表示每次报数到 m 就自杀。
输出最后存活下来的人编号(编号从1开始到n)
5 2
3
/*简单模拟*/
#include <stdio.h>
#include <stdlib.h>
typedef struct nd {
int val;
struct nd *next;
} node;
node *create_node(int val) {
node *n = (node *) malloc(sizeof(node));
n->val = val;
n->next = NULL;
return n;
}
node *josephus_kill(node *head, int m) {
int tmp = 1;
node *pre, *cur = head;
while (cur->next != head)
cur = cur->next;
pre = cur;
cur = head;
while (cur->next != cur) {
if (tmp == m) {
tmp = 1;
pre->next = cur->next;
free(cur);
cur = pre->next;
continue;
}
pre = cur;
cur = cur->next;
tmp++;
}
return cur;
}
int main(void) {
int n, m;
scanf("%d%d", &n, &m);
node dh = {0, NULL}, *cur = &dh;
for (int i = 0; i < n; i++) {
cur->next = create_node(i + 1);
cur = cur->next;
}
cur->next = dh.next;
cur = josephus_kill(dh.next, m);
printf("%d\n", cur->val);
return 0;
}