JosePhus 问题
Josephus问题是下面的游戏:N个人编号1~N,围坐成一个圆圈。从一号人开始传递一个热土豆。经过M次传递后拿着热土豆的人被清除离座,围坐的圆圈缩紧,由坐在被清除人后面的人拿起热土豆继续进行游戏。最后整下的人获胜。因此,如果M=0和N=5,则游戏人依次被清除,5号游戏人获胜。如果M=1和N=5,那么被清除的人的顺序是2,4,1,5。
a.编写一个程序解决在M和N为一般值下的Josephus问题,应使所编程序尽可能地高效率,要确保每个单元都能被清除。
b.这个程序的运行时间是多少?
#include <iostream>
#include <list>
#include <chrono>
using namespace std;
using namespace chrono;
int main()
{
int i, j, n, m, mPrime, numLeft;
list <int > L;
list<int>::iterator iter;
//Initialization
cout<<"enter N (# of people) & M (# of passes before elimination):";
cin>>n>>m;
numLeft = n;
mPrime = m % n;
auto start = system_clock::now();
for (i =1 ; i <= n; i++)
L.push_back(i);
iter = L.begin();
// Pass the potato
for (i = 0; i < n; i++)
{
mPrime = mPrime % numLeft;
if (mPrime <= numLeft/2) // pass forward
for (j = 0; j < mPrime; j++)
{
iter++;
if (iter == L.end())
iter = L.begin();
}
else // pass backward
for (j = 0; j < mPrime; j++)
{
if (iter == L.begin())
iter = --L.end();
else
iter--;
}
cout<<*iter<<" ";
iter= L.erase(iter);
if (iter == L.end())
iter = L.begin();
}
cout<<endl;
auto end = system_clock::now();
auto duration = duration_cast<microseconds>(end - start);
cout << " Consume: " << double(duration.count())*microseconds::period::num / microseconds::period::den << " s(秒)" << endl;
return 0;
}