约瑟夫环(STL详解)

约瑟夫问题是:有 n 只猴子,按顺时针方向围成一圈选大王(编号为 1~n),从第 1 号开始报数,一直数到 m,数到 m 的猴子退到圈外,剩下的猴子再接着从 1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王。编程求输入 n、m 后,输出最后猴王的编号。

尝试使用STL容器进行解答:使用list,遍历并删除

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define MAX_STR_LEN 10
using namespace std;
const int maxn = 100;
vector<int> pile[maxn];
list<int> moneky;
int main()
{
    int n,m;
    while(true)
    {
        cin>>n>>m;
        if(n==0&&m==0)
            break;
        moneky.clear();
        for(int i = 1;i <= n;i++)
        {
            moneky.push_back(i);
        }
        list<int>::iterator it = moneky.begin();
        while(moneky.size()>1)
        {
            for(int i = 1;i < m;++i)
            {
                ++it;
                if(it == moneky.end())  //循环
                    it = moneky.begin();
            }
            it = moneky.erase(it);      //删除那只猴子
            if(it == moneky.end())
            {
                it = moneky.begin();
            }
        }
        cout<<moneky.front()<<endl;
    }
    return 0;
}


  1. 本题使用List容器进行操作,每当报数进行到m的时候,可能会出现圈形报数,这时定义一个迭代器,每迭代到容器末端,就使其指向开头,解决循环问题。

  2. List容器对于猴子出列问题的实现,是定义迭代器,使用迭代器的erase方法,此处注意,使用erase方法后,迭代器会失效,此时需再次将迭代器指向被删除元素后端,如此便可继续进行迭代。

下面补充用vector容器进行约瑟夫环的实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define MAX_STR_LEN 10
using namespace std;
const int maxn = 100;
vector<int> pile;
list<int> moneky;
int main()
{
    int n,m;
    while(true)
    {
        int x = 0;
        cin>>n>>m;
        if(n==0&&m==0)
            break;
        pile.clear();
        for(int i = 1;i <= n;i++)
        {
            pile.push_back(i);
        }
        while(pile.size())
        {
            x = (x + m - 1) % pile.size();
            cout<<pile[x]<<" ";
            pile.erase(pile.begin()+x);
        }
    }
    return 0;
}


此处并未使用迭代器,直接判断下一个出列猴子的位置,然后用%pile.size()进行循环处理即可达到要求

你可能感兴趣的:(数据结构)