约瑟夫环问题(Josephus) 问题
list <int> jos;
list <int> ::iterator jose;
..............//中间的我就不写了..
while (!jos.empty())
{
for (int j=0;j <n;j++) //n为人数
{
for (int k=0;k <m;k++) //m为第m个人出列
{
if (jose==jos.end())
{
jose++=jos.begin();
}
else
jose++;
}
jose--; //多了m次,所以减1;
cout < < *jose < < " ";
jos.erase(jose);
}
}
就只能执行一次,得到第一个出列的人,后面就不行了,好像是出界了,怎么回事呢??
[解决办法]
/*递归实现*/
#include <iostream>
using namespace std;
//本程序以从1开始数,数到3离队为例,其它情况只用少加修改
void make(int *base,int n,int pos,int c)
{
int j=0;
cout < < "NO. " < <++c < < " 第 " < <pos+1 < < "位出列 " < <endl;//输出
base[pos]=0;//踢掉
if(c==n)return; //出口
while(j-3)if(base[pos=(pos+1)%n])j++;//递归点 ,每次数到几这个3就改到几
make(base,n,pos,c);//递归
}
int main()
{
int n,c=0,pos=2;//从N开始数,则把pos改为N-1就行了.
cout < < "请输入总人数 " < <endl;
cin> > n;
int *base=new int[n];
for(int i=0;i <n;i++)base[i]=1;
make(base,n,pos,c);
delete[]base;
system( "PAUSE ");
return 0;
}
[解决办法]
原因在这里 jos.erase(jose);
因为清除了jose指向的元素,导致jose失效,应改为:
jose = jos.erase(jose);
让jose指向所清除元素的后一个元素,这样可以继续下去。