2.约瑟夫环(综合性实验)
问题描述
约瑟夫问题的一种描述是,编号为1, 2, …, n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,位于他顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列。试设计一个程序求出出列顺序。
基本要求
利用单向循环链表存储结构模拟此过程,按照出列的顺序打印出每个人的编号。
测试数据
m的初值为20,密码分别为3、1、7、2、4、8和4(正确的结果应为6、1、4、7、2、3和5)。
实现提示
程序运行后首先要求用户指定初始报数上限值,然后读取每个人的密码(设n≤30)。
本题可使用模板类LinkList,也可使用STL的List容器。
注:当时控制台对齐效果做的不好,哈哈!
【MoshowMenu.h】自制简易菜单v1.02
#include <iostream>
using namespace std;
//②〇①〇〇③〇④〇③〇⑤④ 10软开B(郑锴) 自制简易菜单!
//v1.02<2011.10.09>
//●AddMenu传参由string xxx改为char xxx[],防止vs2010上通过而vs2008报错
//●Choise增加输入缓冲区清楚机制,防止输入"\&~"等字符导致程序卡死
//
void MainMenu()
{
system("Color 2E");
system("Title 10软开B(郑锴)");
cout<<"\n\n\n\n\t\t ★★姓名→郑锴★★★学号→xxxxxxxxxxx ★★\n"
<<"\t \t ***Warning:Don't Ctrl+C Copy Me!Copy必究*** \n \n";
}
void AddMenu(char xxx[])
{
cout<<"\t\t\t\t●"<<xxx<<endl;
}
int Choise()
{
int choise;
cout<<"\n\n\t\t请输入选项:";
cin>>choise;
cin.clear();
cin.sync();
system("cls");
return choise;
}
//应用实例:
//void main()
//{
// int open=1;
// xxxx<int> x;
// while(open)
// {
// MainMenu();
// AddMenu("*.初始化x");
// AddMenu("0.退出程序");
// AddMenu("1.__n____");
// AddMenu("2._______");
// switch(Choise())
// {
// case 0:
// open=0;
// cout<<"程序即将退出!"<<endl;
// break;
// case 1:
// int n;
// cout<<"输入n:"
// x.xxxx(n);
// break;
// case 2:
// x.xxxx();
// break;
// default:
// cout<<"输入错误!"<<endl;
// break;
// }
// }
// system("pause");
//}
【InitList.h】//自制的链表类
#include<iostream>
using namespace std;
class Node //链表
{
public:
int data;
Node *next;
};
Node *initList(int n) //函数:生成链表存放数据
{
Node *list = new Node;
Node *p = list;
p->data = 1;
p->next = 0;
for (int i = 2; i <= n; i++)
{
Node *temp = new Node;
temp->data = i;
temp->next = 0;
p->next = temp;
p = temp;
}
p->next = list;
return list;
}
void Print(Node *list) //函数:打印链表
{
if (list)
{
Node *p = list;
cout<<p->data;
while (p->next != list)
{
p = p->next;
cout<<"→"<<p->data;
}
}
cout<<endl;
}
【moshowmain.cpp】主函数
#include"InitList.h"
#include"MoshowMenu.h"
void main() //Moshow魔手.郑锴
{
int n;
int m[20];
//入座
MainMenu();
AddMenu("请输入围坐一圈的人数n:");
cin>>n;
Node *mylist = initList(n);
//给编号!
AddMenu("初始编号是:");
Print(mylist);
//初始化密码!
AddMenu("请输入初始密码m:");
cin>>m[0];
for (int i = 1; i <= n; i++)
{
cout<<"请输入第"<<i<<"个人的密码:";
cin>>m[i];
}
//逐个按顺序出列!
AddMenu("出列顺序是: ");
int j = 0;
Node *p = mylist;
Node *t = new Node;
while( p->next != p)
{
for(int k = 1 ; k < m[j] ; k++ )
{
t = p;
p = p->next;
}
cout<<p->data<<"→";
j = p->data;
t->next = p->next;
delete p;
p = t->next;
}
cout<<p->data<<"#end! \n"; //不要忘记还有最后一个人
system("pause");
}