标签:
题目:有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)。
标签:
原文地址:http://www.cnblogs.com/ZRBYYXDM/p/5142918.html