用c语言写出编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将它的密码作为新的m值,从它的顺时针方向的下一个人开始重新从1报数,如此下去,直至全部人出列为止。最后按照出列的顺序输出各人的编号
时间: 2023-10-21 21:03:39 浏览: 101
好的,以下是我给出的 C 语言代码实现。
```c
#include <stdio.h>
#include <stdlib.h>
int* josephus(int n, int m, int* passwords) {
// 初始化编号和密码数组
int* nums = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
nums[i] = i + 1;
}
// 初始化出列顺序和当前报数的人在编号数组中的索引
int* order = (int*)malloc(n * sizeof(int));
int index = 0;
// 当还有人没出列时
while (n > 0) {
// 计算当前报数的人在数组中的索引
index = (index + m - 1) % n;
// 将当前报数的人的密码作为新的 m 值
m = passwords[nums[index]-1];
// 将当前报数的人从数组中移除并添加到出列顺序的数组中
order[n-1] = nums[index];
for (int i = index; i < n-1; i++) {
nums[i] = nums[i+1];
}
n--;
}
// 返回出列顺序
return order;
}
int main() {
int n = 7;
int m = 3;
int passwords[] = {7, 6, 5, 4, 3, 2, 1};
int* order = josephus(n, m, passwords);
for (int i = 0; i < n; i++) {
printf("%d ", order[i]);
}
printf("\n");
free(order);
return 0;
}
```
在上面的代码中,我们同样使用了一个数组来记录编号为 1 到 n 的人。每次报数时,计算出当前报数的人在数组中的索引,将其从数组中移除并添加到出列顺序的数组中。同时,将当前报数的人的密码作为新的 m 值。最后输出出列顺序的数组。注意,在 C 语言中需要手动分配和释放内存。
阅读全文