所谓约瑟夫问题,是指:有n个人围坐在圆桌周围,每个人都有固定的编号。从第s(<=n)个人开始报数(按顺时针方向,从1开始),报到m的人出列(离开),接着再从出列者的下一个人开始报数(仍然从1开始),报到m的人又出列,......,如此重复进行,直到所有的人都出列。对任意给定的n,s和m,按出列先后顺序输出每个出列者的编号
//代码实现部分:
#include <stdafx.h> #include <iostream> #include <vector> #include <algorithm> #include <iomanip> using namespace std;
//求解约瑟夫问题的函数 //s 表示从第s个人开始报数,m 表示报到m的人出列,v1 表示原始数据, v2 表示出列的数据 template <typename T> void josephu(int s,int m,vector<T>& v1,vector<T>& v2);
int main() { vector<int> original,ultimate; int n,val,s,m; //s 表示从第s个人开始报数,m 表示报到m的人出列,n 表示有n个人,val 表示临时变量 cout<<"请输入人数n:"; cin>>n; original.reserve(n); //设置容量为n ultimate.reserve(n); //设置容量为n cout<<"输入 "<<n<<" 个元素,用空格隔开,最后以'enter'键结束:"<<endl; for(int i=0;i<n;i++) { cin>>val; original.push_back(val); } cout<<"输入报数的起始位置和报数值s和m:"; cin>>s>>m; josephu(s,m,original,ultimate); cout<<endl<<"出列顺序:"<<endl; vector<int>::iterator iter = ultimate.begin(); //定义迭代器 while(iter!=ultimate.end()) cout<<setw(5)<<*iter++; cout<<endl; return 0; }
template <typename T> void josephu(int s,int m,vector<T>& v1,vector<T>& v2) //s 表示从第s个人开始报数,m 表示报到m的人出列,v1 表示原始数据, v2 表示出列的数据 { vector<T>::iterator iter1 = v1.begin(); vector<T>::iterator iter2 = v2.begin(); for(int i=1;i<s;i++,iter1++) //找到第一个报数者 if(iter1 == v1.end()) iter1 = v1.begin(); while(!v1.empty()) { for(int i=1;i<m;i++) if(++iter1 == v1.end()) //寻找报数者 iter1 = v1.begin(); v2.insert(iter2++,*iter1); //将出列者插到v2中 v1.erase(iter1); //从v1中删除出列者 if(iter1 == v1.end()) iter1 = v1.begin(); } }