1011: 约瑟夫(Joseff)问题求解(2)
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 411 Solved: 203
[Submit][Status][Web Board]
Description
约瑟夫(Joseff)问题求解。n个人围成一圈,编号依次为1,2,。。。。n,从第一个人开始报数,m号出圈,再从下一个开始报数,。。。,m号出圈,直至所有人出圈。求出圈的次序。
要求采用仅设尾指针的单向循环链表实现。已知类的定义、部分成员函数及主函数代码如下(勿改动)。
//结点结构
template <class T>
struct Node
{
T data;
Node<T> *next;
};
//单向循环链表类
template <class T>
class LinkList
{
public:
LinkList( ); //建立没有头结点的空链表
~LinkList(); //析构函数
void RInsert(T x); //在链表表尾插入元素x
void Create(int n); //利用RInsert创建仅有尾指针的单向循环链表(不设置头结点)
void Joseff(int m); // 约瑟夫问题求解
void DispList( ); //遍历单链表,按序号依次输出各元素
private:
Node<T> *rear; //尾指针
};
//创建空的循环表
template <class T>
LinkList<T>:: LinkList( ){
rear=NULL;
}
//析构函数:释放链表结点所占内存单元
template <class T>
LinkList<T>:: ~LinkList( ){
Node<T> *s;
if(rear) //链表非空析构
{
s=rear->next;
while (s!=rear){
rear->next=s->next;
delete s;
s=rear->next;
}
delete s;
}
}
//创建n个数据的链表
template <class T>
void LinkList<T>::Create(int n){
int i;
for(i=1;i<=n;i++)
RInsert(i);
}
/*
*前置条件:单链表存在
*输 入:无
*功 能:单链表遍历
*输 出:输出所有元素
*后置条件:单链表不变
*/
template <class T>
void LinkList<T>::DispList( )
{
Node<T> *p;
if(rear) //链表非空输出数据
{
for(p=rear->next;p!=rear;p=p->next)
cout<<p->data<<" ";
cout<<p->data<<" ";
}
cout<<endl;
}
int main( ){
LinkList<int> sa;
int m,n;
cin>>n>>m;
sa.Create(n); //创建n个人(编号1~n)的链表
sa.DispList(); // 遍历链表,输出编号
sa.Joseff(m); // 输出出圈人的编号次序
return 0;
}
Input
输入次序为n,m
Output
Sample Input
10 5
Sample Output
1 2 3 4 5 6 7 8 9 10 5 10 6 2 9 8 1 4 7 3
#include <iostream>
using namespace std;
//结点结构
template<class T>
struct Node {
T data;
Node<T> *next;
};
//单向循环链表类
template<class T>
class LinkList {
public:
LinkList(); //建立没有头结点的空链表
~LinkList(); //析构函数
void RInsert(T x); //在链表表尾插入元素x
void Create(int n); //利用RInsert创建仅有尾指针的单向循环链表(不设置头结点)
void Joseff(int m); // 约瑟夫问题求解
void DispList(); //遍历单链表,按序号依次输出各元素
private:
Node<T> *rear; //尾指针
};
//创建空的循环表
template<class T>
LinkList<T>::LinkList() {
rear = NULL;
}
//析构函数:释放链表结点所占内存单元
template<class T>
LinkList<T>::~LinkList() {
Node<T> *s;
if (rear) //链表非空析构
{
s = rear->next;
while (s != rear) {
rear->next = s->next;
delete s;
s = rear->next;
}
delete s;
}
}
//创建n个数据的链表
template<class T>
void LinkList<T>::Create(int n) {
int i;
for (i = 1; i <= n; i++)
RInsert(i);
}
template<class T>
void LinkList<T>::DispList() {
Node<T> *p;
if (rear) //链表非空输出数据
{
for (p = rear->next; p != rear; p = p->next)
cout << p->data << " ";
cout << p->data << " ";
}
cout << endl;
}
template<class T>
void LinkList<T>::RInsert(T x) {
Node<T> *s = new Node<T>;
s->data = x;
if (rear == NULL) {
rear = s;
rear->next = s;
} else {
s->next = rear->next;
rear->next = s;
rear = s;
}
}
template<class T>
void LinkList<T>::Joseff(int m) {
if (rear) {
int cnt = 0;
while (rear != rear->next) {
Node<T> *q = rear->next;
cnt++;
if (cnt == m) {
rear->next = q->next;
cout << q->data << " ";
cnt = 0;
delete q;
} else
rear = rear->next;
}
cout << rear->data;
delete rear;
rear = NULL;
}
}
int main() {
LinkList<int> sa;
int m, n;
cin >> n >> m;
sa.Create(n); //创建n个人(编号1~n)的链表
sa.DispList(); // 遍历链表,输出编号
sa.Joseff(m); // 输出出圈人的编号次序
return 0;
}