问题:
约瑟夫是公元1世纪的一名著名的历史学家,所谓约瑟夫问题,可简单描述如下:有15个人排成一圈,并给他们编号1——15,现在从1号开始报数,报数4的人退出队列,余下的人从退出者下一个位置开始继续报数,直到整个队列中只剩下一个人为止,请问这个人编号是几?
问题分析:
1、编码:用整型数列1——15代表15个人的编码。
2、容器:由于报数为4的人要出队,就相当于不断有元素要删除,所以用链表较好。特别用循环链表最好。
3、算法:对链表进行遍历,用一个计数器和链表的迭代器结合,只要计数器到4就将相应的迭代器指示的元素删除,直到剩下最后一个元素。
代码:
#include<iostream>
#include<iterator>
#include<list>
using namespace std;
void main()
{
list<int> l;
for(int i=1;i<16;i++)
{
l.push_back(i);
}
cout<<"开始状态:"<<endl;
copy(l.begin(),l.end(),ostream_iterator<int>(cout,"\t"));
cout<<endl;
list<int>::iterator it=l.begin();
while(l.size()!=1)
{
for(int j=0;j<3;j++)
{
it++;
if(it==l.end()) //由于stl中的list不是循环链表,所以这里手动将其指向链表的开始
{
it=l.begin();
}
}
it=l.erase(it);
if(it==l.end()) //此处也要判断一下是否要把链表循环起来。
{
it=l.begin();
}
}
cout<<"最后剩下谁:";
copy(l.begin(),l.end(),ostream_iterator<int>(cout,"\t"));
cout<<endl;
system("pause");
}