• 约瑟夫环问题


    题目:有N个人做成一圈玩游戏,编号为1至N。从编号为1的人开始传递马铃薯。M次传递后,持有马铃薯的人退出游戏。圈缩小,然后游戏从退出的人下面的人开始,继续进行。最终留下来的人获胜。写出一个程序解决约瑟夫环问题,此时M和N为任意值。

    编程如下:

    #include <iostream>
    
    using namespace std;
    
    template <typename Object>
    class List
    {
        private:
            struct Node                             //List内部维护的节点类
            {
                Object data;
                Node *prev;
                Node *next;
    
                Node( const Object &d = Object(),Node *p = NULL,Node *n = NULL )
                    : data( d ),prev( p ),next( n ) { }
            };
    
        public:
            class const_iterator                    //常量迭代器
            {
                public:
                    const_iterator() : current( NULL )
                    { }
    
                    const Object &operator*() const
                    { return retrieve(); }
    
                    const_iterator &operator++()
                    {
                        current = current->next;
                        return *this;
                    }
    
                    const_iterator operator++( int )
                    {
                        const_iterator old = *this;
                        ++( *this );
                        return old;
                    }
    
                    bool operator== ( const const_iterator &rhs ) const
                    { return current == rhs.current; }
    
                    bool operator!= ( const const_iterator &rhs ) const
                    { return !( *this == rhs ); }
    
                protected:
                    Node *current;
    
                    Object &retrieve() const
                    { return current->data; }
    
                    const_iterator( Node *p ) : current( p )
                    { }
    
                    friend class List<Object>;
            };
    
            class iterator : public const_iterator  //迭代器类继承自常量迭代器类
            {
                public:
                iterator()
                { }
    
                Object &operator*()
                { return const_iterator::retrieve(); }
    
                const Object &operator*() const
                { return const_iterator::operator*(); }
    
                iterator &operator++()
                {
                    const_iterator::current = const_iterator::current->next;
                    return *this;
                }
    
                iterator operator++( int )
                {
                    iterator old = *this;
                    ++( *this );
    
                    return old;
                }
    
                protected:
                    iterator( Node *p ) : const_iterator( p )
                    { }
    
                    friend class List<Object>;
            };
    
        public:
            List()
            { init(); }
    
            ~List()
            {
                clear();
                delete head;
                delete tail;
            }
    
            List( const List &rhs )
            {
                init();
                *this = rhs;
            }
    
            const List &operator= ( const List &rhs )
            {
                if ( this == &rhs )
                    return *this;
                clear();
                for ( const_iterator itr = rhs.begin() ; itr != rhs.end() ; ++itr )
                    push_back( *itr );
    
                return *this;
            }
    
            iterator begin()
            { return iterator( head->next ); }
            const_iterator begin() const
            { return const_iterator( head->next ); }
            iterator end()
            { return iterator( tail ); }
            const_iterator end() const
            { return const_iterator( tail ); }
    
            int size() const
            { return theSize; }
            bool empty() const
            { return size() == 0; }
    
            void clear()
            {
                while ( !empty() )
                    pop_front();
            }
    
            Object &front()
            { return *begin(); }
            const Object &front() const
            { return *begin(); }
            Object &back()
            { return *--end(); }
            const Object &back() const
            { return *--end(); }
            void push_front( const Object &x )
            { insert( begin(),x ); }
            void push_back( const Object &x )
            { insert( end(),x ); }
            void pop_front()
            { erase( begin() ); }
            void pop_back()
            { erase( --end() ); }
    
            iterator insert( iterator itr,const Object &x )
            {
                Node *p = itr.current;
                theSize++;
                return ( p->prev = p->prev->next = new Node( x,p->prev,p ) );
            }
    
            iterator erase( iterator itr )
            {
                Node *p = itr.current;
                iterator retVal( p->next );
                p->prev->next = p->next;
                p->next->prev = p->prev;
                delete p;
                theSize--;
    
                return retVal;
            }
    
            iterator erase( iterator start,iterator end )
            {
                for ( iterator itr = start ; itr != end; )
                    itr = erase( itr );
    
                return end;
            }
    
        private:
            int theSize;
            Node *head;
            Node *tail;
    
            void init()
            {
                theSize = 0;
                head = new Node;
                tail = new Node;
                head->next = tail;
                tail->prev = head;
            }
    };
    
    void PrintList( List<int> &list )                   //打印List
    {
        for ( List<int>::iterator itr = list.begin() ; itr != list.end() ; ++itr )
            cout << *itr << " ";
    
        cout << endl;
    }
    
    int main( void )
    {
        List<int>Number;
        int count = 0;
        cout << "参加游戏的是几个人?" << endl;
        cin >> count;
    
        int M = 0;
        cout << "传递几次人员退出?" << endl;
        cin >> M;
    
        for ( int i = 0 ; i != count ; ++i )
            Number.push_back( i + 1 );
    
        cout << "游戏刚开始时人员情况:" << endl;
        PrintList( Number );
    
        count = 0;
        List<int>::iterator iter = Number.begin();
        while ( Number.size() - 1 ){                        //剩下最后一个人时退出循环
            for ( int j = 0 ; j != M ; j++ ){
                if ( iter == Number.end() )                 //当循环到最后,迭代器指向第一个人。
                    iter = Number.begin();
                iter++;
            }
    
            if ( iter == Number.end() )                     //当循环到最后,迭代器指向第一个人。
                    iter = Number.begin();
    
            cout << "要退场的人的编号是:" << *iter << endl;
            iter = Number.erase( iter );
    
            count++;
            cout << "" << count << "轮后人数情况:" << endl;
            PrintList( Number );
        }
    
        cout << "胜利者是:" << *( Number.begin() ) << "" << endl;
    
        return 0;
    }

    运行效果:

    运行时间关键在于M和N。Number链表迭代N-1次,且M≠0时,for循环的运行时间是O(M),每次删除节点就调用for循环,运行时间应该是O(MN)。

    我们一路奋战,不是为了改变世界,而是不让世界改变我们 ——《熔炉》
  • 相关阅读:
    DataSet生成gb2312编码的xml
    利用SendMessage实现C#进程间通信
    DataSet与Xml之间的转换
    xml解析
    当前时间加指定的几个月
    Excel利用poi导入导出(上)
    mybatis.generator.plugins生成基础类
    Excel利用poi导入导出(下)
    ASP.NET 中的Session统一管理
    太幸福了,没有比我们更开放的网络了!
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5142918.html
Copyright © 2020-2023  润新知