(easy版本)已知 n 个人(以编号1, 2, 3 ,4, 5 ,6 ... .. .n)围坐一张圆桌周围。从编号为s 的人开始报数,数到m 的那个人出列;他的下一个人又从 1开始报数,数到m的那个人又出列;依次规律重复下去,直到圆桌周围的人全部出列。
#include <iostream>
using namespace std;
struct node
{
int data;
node *next;
};
main()
{
/*假设共有n人,从第s个人开始数数,每数到m该人出列,后面的人重新开始数,知道全部人出列*/
int n,s,m;
node *current,*prev;
node *head=new node;
head->data=1; //这里的头指针等同于第一个节点
prev=head;
cout << "Input the n,s,m(separate with space):";
cin >> n >> s >> m;
for(int i=2;i<=n;i++) //建立循环链表
{
current = new node;
current->data = i;
prev->next=current;
prev=current;
}
current->next=head;
current = head; //遍历循环链表,输出序列
do
{
cout << current->data<< " ";
current = current->next;
} while(current!=head);
current = head; //将current置于第s个位置
for(int i=1;i<s;i++)
{
current = current->next;
}
cout << endl;
for(int i=1;i<=n;i++) //共循环n轮,得到一个整体的输出序列
{
for(int j=1;j<m;j++)
{
prev=current; //在current前一个位置
current = current->next;
}
cout << current->data << " ";
prev->next = current->next;
delete current;
current = prev->next;
}
}
(hard版本)题目:约瑟夫双向生死游戏是在约瑟夫生者死者游戏的基础上,正向计数后反向计数,然后再正向计数。具体描述如下:30(NumofPeople)个旅客同乘一条船,因为严重超载,加上风高浪大,危险万分;因此船长告诉乘客,只有将全船一半(NumofKilled)的旅客投入海中,其余人才能幸免遇难。无奈,大家只得同意这种办法,并议定30个人围成一圈,由第一个人开始,顺时针依次报数,数到第9(ForwardCount)人,便把他投入大海中,然后从他的顺时针的下一个人数起,逆时针数到第5(ReverseCount)人,将他投入大海,然后从他逆时针的下一个人数起,顺时针数到第9人,再将他投入大海,如此循环,直到剩下15个乘客为止。问哪些位置是将被扔下大海的位置。
#include <iostream>
using namespace std;
struct node
{
int data;
node *prior,*next;
};
main()
{
/*假设共有n人,从第s个人开始数数,后面的人重新开始数,直到15人出列*/
int n,s;
cout << "Input the n,s(separate with space):";
cin >> n >> s ;
node *current,*prev;
node *head=new node; //这次head指向一个圈, head在圈外 ,head->next是第一个节点
head->next=head;
head->prior=head;
prev=head;
for(int i=1;i<=n;i++) //建立双循环链表
{
current = new node;
current->data = i;
prev->next=current;
current->prior=prev;
prev=current;
}
current->next=head->next;
head->next->prior=current;
current = head->next; //遍历循环链表,输出序列
for(int i=1;i<=n;i++)
{
cout << current->data<< " ";
current = current->next;
}
current = head->next; //将current置于第s个位置
for(int i=1;i<s;i++)
{
current = current->next;
}
cout << endl;
for(int i=1;i<=15;i++) //共循环15轮,得到一个输出序列
{
if(i%2==1) // 正向
{
for(int j=1;j<9;j++)
{
prev=current; //指向前一个位置
current=current->next;
}
cout<<current->data<<" ";
prev->next=current->next;
current->next->prior=prev;
delete current;
current=prev->next;
}
else //逆向
{
for(int j=1;j<5;j++)
{
prev=current; //指向后一个位置
current=current->prior;
}
cout<<current->data<<" ";
prev->prior=current->prior;
current->prior->next=prev;
delete current;
current=prev->prior;
}
}
return 0;
}
截图: