【XDOJ2026秋数据结构】729.数据结构-约瑟夫环【Compash个人题解】
729.约瑟夫环
问题描述
编号为 1,2,...,n 的 n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。现在给定一个随机数 m>0,从编号为 1 的人开始,按顺时针方向 1 开始顺序报数,报到 m 时停止。报m 的人出圈,同时留下他的密码作为新的 m 值,从他在顺时针方向上的下一个人开始,重新从 1 开始报数,如此下去,直至所有的人全部出圈为止。试设计程序求解出列顺序。
问题输入
输入数据第一行为两个正整数 n 和 m,分别表示人的个数及初始随机数,每组数据的第二行
为 n 个整数,表示每个人持有的密码。
问题输出
用一行输出 n 个整数表示依次出圈人的编号,整数之间用空格分隔。
输入样例
//输入样例
7 20
3 1 7 2 4 8 4
输出样例
//输出样例
6 1 4 7 2 3 5
#include<iostream>
#include<cstddef>
#include<vector>
int n, m;
std::vector<int> nums;
struct ListNode
{
int data;
int number;
struct ListNode* next;
ListNode(int x, int num) : data(x), number(num), next(NULL) {}
};
void insertNode(ListNode*& head, int data, int number)
{
ListNode* node = new ListNode(data, number);
if (head == NULL)
{
head = node;
return;
}
else
{
ListNode* p = head;
while (p->next) p = p->next;
p->next = node;
}
}
int main()
{
std::cin >> n >> m;
ListNode* l = NULL;
for (int i = 1; i <= n; i++)
{
int data;
std::cin >> data;
insertNode(l, data, i);
}
ListNode* p = l;
while (p->next)
{
p = p->next;
}
//p指向最后一个
//现在开始循环
p->next = l;
ListNode* cur = l;
//pre是cur的前驱,一会方便删cur
ListNode* pre = p;
//有count = n个人,现在开始大逃杀
int count = n;
while (count)
{
for (int i = 0; i < (m-1)%count; i++)
{
pre = cur;
cur = cur->next;
}
//此人的密码作为新的m
m = cur->data;
//记录当前节点的编号
nums.push_back(cur->number);
//删除节点
pre->next = cur->next;
ListNode* del = cur;
cur = cur->next;
delete del;
count--;
}
for (int i = 0; i < nums.size(); i++)
{
std::cout << nums[i] << ' ';
}
return 0;
}

浙公网安备 33010602011771号