【题目描述】
N个人围成一圈,从第一个人开始报数,数到M的人出圈;再由下一个人开始报数,数到M的人出圈;…输出依次出圈的人的编号。
【输入】
输入N和M。
【输出】
输出一行,依次出圈的人的编号。
【输入样例】
8 5
【输出样例】
5 2 8 7 1 4 6 3
【提示】
【数据范围】
对于所有数据,2≤N,M≤1000
【题目链接】
#include <stdio.h>
#include <stdlib.h>
void josephus(int n, int m)
{
int *a = (int *)malloc(n * sizeof(int)); // 动态分配数组用于存储每个人的编号
int i;
for (i = 0; i < n; i++)
a[i] = i + 1;
int index = 0; // 当前报数的编号在数组中的索引
int count = n; // 当前剩余人数
// 模拟淘汰过程,直到只剩下一个人
while (count > 1)
{
// 找到要出圈的人的位置
index = (index + m - 1) % count;
printf("%d ", a[index]); // 输出出圈的人的编号
// 将出圈的人从数组中删除,并将其后面的人向前移动一个位置
int i;
for (i = index; i < count - 1; i++)
a[i] = a[i + 1];
count--;
}
// 输出最后生存的人的编号
printf("%d", a[0]);
free(a); // 释放内存
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
// 解决约瑟夫问题,输出每次出圈的人的编号和最后生存的人的编号
josephus(n, m);
return 0;
}
下面这个错误,但不知道为什么
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node* next;
} Node;
Node* createCircularList(int n)
{
Node* head = NULL;
Node* prev = NULL;
int i;
// 创建循环链表
for (i = 1; i <= n; i++)
{
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = i;
if (head == NULL)
{
head = newNode;
}
else
{
prev->next = newNode;
}
newNode->next = head;
prev = newNode;
}
return head;
}
void eliminatePeople(Node** head, int m)
{
Node* current = *head;
Node* prev = NULL;
// 找到开始报数的人
while (current->next != *head)
{
current = current->next;
}
// 报数并淘汰人,直到只剩下一个人为止
while (*head != (*head)->next)
{
// 数到 M 的人出圈
int i;
for (i = 1; i < m; i++)
{
prev = current;
current = current->next;
}
// 出圈操作
prev->next = current->next;
// 输出出圈的人的编号
printf("%d ", current->data+1);
// 释放淘汰的节点内存
free(current);
// 移动到下一个人
current = prev->next;
}
// 释放最后剩余的节点内存
free(*head);
*head = NULL;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
// 创建循环链表
Node* head = createCircularList(n);
// 淘汰人,直到只剩下一个人为止,并输出出圈的人的编号
eliminatePeople(&head, m);
return 0;
}