编号为1,2,......,n的n个人按照顺时针方向围坐一圈,每个人有且只有一个密码(正整数)。一开始任选一个正整数作为报数上限值,从第一个人开始顺时针方向自1开始报数,报到m时停止报数。报m 的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新报数,如此下去,直到所有人全部出列为止。设计一个程序来求出出列顺序
时间: 2023-05-04 08:00:33 浏览: 119
这是一个编码问题,需要先将其转换为字符串。题意大意是:有n个人按照顺时针方向围坐一圈,每个人有且只有一个密码(正整数),从第一个人开始,选一个正整数作为报数上限值,报到上限值时停止报数。报数到m的人出列,将他的密码作为新的m值,从他在顺时针方向下一个人开始重新报数直到所有人出列为止。需要设计一个程序来求出出列顺序。
相关问题
带密码的约瑟夫问题:编号为1,2,......,n的n个人按照顺时针方向围坐一圈,每个人有自己的编号(正整数)、姓名和密码(正整数)三个数据项。一开始任选一个正整数作为报数上限值,从第一个人开始顺时针
报数,报到上限值的人出列,然后从他的下一个人开始重新报数,直到所有人都出列为止。但是,每个人的密码不同,只有知道密码的人才能出列。问:按照什么顺序可以使得所有人都能够出列?
答:按照密码从小到大的顺序进行报数,即先找到密码最小的人,然后从他开始顺时针报数,报到上限值的人出列,然后再从他的下一个密码最小的人开始重新报数,直到所有人都出列为止。这样可以保证每个人都能够出列,因为每次出列的人都是密码最小的人,而且每个人的密码都不同,所以不会出现密码相同的情况。
用c语言按照要求完成下列数据结构课程设计,设计目的:1. 掌握单向循环链表的建立。 2. 掌握单向循环链表的操作。 设计内容:编号是 1,2,„„,n 的 n 个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。一 开始任
意人可以指定一个起始编号,从这个编号的人开始从 1 报数,依次往下,数到给定的密码的人出圈,直到圈中只剩下一个人为止。请你用 C 语言实现这个约瑟夫环问题的求解。
以下是 C 语言实现代码:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int num;
int password;
struct node *next;
} Person;
Person *createList(int n) { // 创建循环链表
Person *head, *tail, *p;
head = tail = (Person *)malloc(sizeof(Person)); // 创建头结点
head->num = 1;
printf("Please input the password for Person %d: ", 1);
scanf("%d", &head->password);
for (int i = 2; i <= n; i++) { // 创建 n 个结点
p = (Person *)malloc(sizeof(Person));
p->num = i;
printf("Please input the password for Person %d: ", i);
scanf("%d", &p->password);
tail->next = p; // 将新结点插入到链表尾部
tail = p;
}
tail->next = head; // 将链表尾部指向头结点,形成循环链表
return head;
}
void josephus(int n, int m, Person *head) { // 约瑟夫环问题求解
Person *p = head, *q;
int count = 0;
while (p->next != p) { // 当链表中只有一个结点时跳出循环
count++;
if (count == m) { // 找到要出圈的结点
printf("Person %d is out!\n", p->num);
q->next = p->next; // 删除该结点
free(p);
p = q->next;
count = 0;
} else {
q = p;
p = p->next;
}
}
printf("Person %d is the last one!\n", p->num); // 输出最后留下的结点
free(p);
}
int main() {
int n, m;
printf("Please input the number of persons: ");
scanf("%d", &n);
printf("Please input the password to count off: ");
scanf("%d", &m);
Person *head = createList(n); // 创建循环链表
josephus(n, m, head); // 约瑟夫环问题求解
return 0;
}
```
这段代码中,我们首先定义了一个 `Person` 结构体,用于存储每个人的编号和密码。然后,我们定义了 `createList` 函数,用于创建循环链表。在 `createList` 函数中,我们先创建头结点,然后依次创建 n 个结点并插入到链表尾部,最后将链表尾部指向头结点,形成循环链表。
接着,我们定义了 `josephus` 函数,用于求解约瑟夫环问题。在 `josephus` 函数中,我们用一个循环来遍历链表,每次数到给定的密码就将该结点删除。具体实现中,我们用两个指针 p 和 q 分别指向当前结点和当前结点的前一个结点,便于删除结点后修改链表指针。
最后,在 `main` 函数中,我们先读入人数和密码,然后调用 `createList` 函数创建循环链表,最后调用 `josephus` 函数求解约瑟夫环问题。
阅读全文