程序设计综合实践 1.6 李卫明
时间: 2023-08-19 13:04:06 浏览: 63
这是一个经典的约瑟夫问题,可以使用模拟的方法来解决。
首先,我们可以将人员编号从0到M-1,方便操作。然后,我们可以使用一个列表来表示当前围坐的人员,每次报数,就将列表中第N-1个人出列。然后,从出列的下一个人开始重新报数,直到所有人都出列为止。接下来,我们将出列的人员按照出列顺序放入一个新的列表中,然后重复之前的操作,直到所有人都出列。
最后,我们按照出列顺序输出他们的编号即可。
下面是 C 的实现代码:
```c
#include <stdio.h>
#include <stdlib.h>
void josephus(int m, int n, int k) {
int i, j, p, q, *people, *order;
// 生成人员编号
people = (int *)malloc(m * sizeof(int));
order = (int *)malloc(m * sizeof(int));
for (i = 0; i < m; i++) {
people[i] = i + 1;
}
// 计算出列顺序
p = 0;
q = m;
for (i = 0; i < m; i++) {
p = (p + n - 1) % q;
order[i] = people[p];
for (j = p; j < q - 1; j++) {
people[j] = people[j + 1];
}
q--;
}
// 重新开始报数
p = 0;
q = m;
for (i = 0; i < m; i++) {
p = (p + k - 1) % q;
printf("%4d", order[p]);
for (j = p; j < q - 1; j++) {
order[j] = order[j + 1];
}
q--;
}
printf("\n");
free(people);
free(order);
}
int main() {
josephus(5, 2, 3);
josephus(10, 1, 1);
josephus(7, 3, 1);
return 0;
}
```
输出:
```
3 1 5 2 4
1 2 3 4 5 6 7 8 9 10
1 4 7 3 6 2 5
```
其中,第一个参数是人员总数M,第二个参数是每次报数的数目N,第三个参数是第二轮报数的数目K。