约瑟夫环
时间限制: 1s
类别: DS:数组与链表->链表--较难
问题描述
用单链表解决约瑟夫问题。约瑟夫问题为:n个人围成一圈,从第一个人开始报数1, 2, …, m,数到m的人出圈,然后从出圈的下一个人(m+1)开始重复此过程,直到全部人出圈,于是得到一个出圈序列,如当n=8,m=4时,则得到的出圈序列为4, 8, 5, 2, 1, 3, 7, 6。
输入说明
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。测试数据仅一行,包括两个整数n和m,n表示人数,m表示淘汰数,两个整数用一个空格隔开。
输出说明
输出出圈序列。每两个整数之间以一个空格分隔。行首与行尾无多余空格。
#include<iostream>
#include<vector>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode() : val(0), next(NULL) {}
ListNode(int x) : val(x), next(NULL) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
int getlength(ListNode*head)
{
if(!head) return 0;
ListNode*p=head;
int n=1;
while(p->next!=nullptr)
{
p=p->next;
n++;
}
return n;
}
void josephus(ListNode* &head, int m)
{
if (!head || m == 0) return;
ListNode *cur = head, *prev = nullptr;
while (cur->next != cur) // Until only one node is left
{
for (int count = 1; count < m; ++count)
{
prev = cur;
cur = cur->next;
}
// Remove the m-th node
prev->next = cur->next;
if (cur == head) head = cur->next; // Update head if needed
cout<<cur->val<<" ";
delete cur;
cur = prev->next;
}
cout << cur->val << endl;
}
ListNode *createCircularList(int len)
{
ListNode *head = nullptr, *tail = nullptr;
for(int i = 1; i <= len; i++)
{
ListNode* node = new ListNode(i);
if (!head)
{
head = node;
tail = node;
}
else
{
tail->next = node;
tail = node;
}
if (i == len) tail->next = head; // Make the list circular
}
return head;
}
int main()
{
int length, n;
cin >> length >> n;
ListNode* head = createCircularList(length);
josephus(head, n);
delete head; // Clean up the last node
return 0;
}