汉诺塔的变形题目:
现在有多个柱子,柱子上有若干盘子,盘子的摆放要求编号小的盘子一定在编号大的盘子的上面。初始时,若干个盘子分散在这些柱子上,要求实现一个算法,将盘子移动到其他柱子上。
这个题目其实并不是很难,但是一定要分析清楚和能够熟练使用递归算法。
#include <iostream>
#include <list>
#include <stack>
#include <algorithm>
using namespace std;
class HanoiWithStatus
{
public:
HanoiWithStatus( int n)
{
m_pegs = n;
InitialPegStatus = new list< int>[n];
FinalPegStatus = new list< int>[n];
}
void Rearrange();
void MoveToFinal();
void MoveToContainer( int i);
void Move();
list< int>* InitialPegStatus;
list< int>* FinalPegStatus;
void move( int i, int src, int dest, int buffer);
void MoveOnePlateToTarget( int plate);
private:
int m_pegs;
int m_plates;
};
void HanoiWithStatus::Rearrange()
{
m_plates = 0;
for( int i= 0;i<m_pegs;i++)
m_plates +=InitialPegStatus[i].size();
for ( int i= 0 ;i<m_plates;i++)
{
cout<< " Arranging "<<i<<endl;
MoveToContainer(i);
}
for ( int i= 0 ;i<m_pegs;i++)
cout<<InitialPegStatus[i].size()<<endl;
}
void HanoiWithStatus::move( int i, int src, int dest, int buffer)
{
if(i>= 0)
{
move(i- 1, src, buffer, dest);
InitialPegStatus[src].remove(i);
InitialPegStatus[dest].push_front(i);
cout<< " Move "<<i<< " from "<<src<< " to "<<dest<<endl;
move(i- 1, buffer, dest, src);
}
}
void HanoiWithStatus::MoveToContainer( int plate)
{
int owningIndex = - 1, containingIndex = - 1;
int bufferIndex = - 1;
for( int i= 0;i<m_pegs;i++)
{
list< int>::iterator itr = find(InitialPegStatus[i].begin(), InitialPegStatus[i].end(), plate);
if(itr == InitialPegStatus[i].end())
continue;
else{
owningIndex = i;
break;
}
}
if(owningIndex >= 0)
{
for( int i= 0;i<m_pegs;i++)
{
list< int>::iterator itr = find(InitialPegStatus[i].begin(), InitialPegStatus[i].end(), plate+ 1);
if(itr == InitialPegStatus[i].end())
continue;
else{
containingIndex = i;
break;
}
}
for( int i = 0;i<m_pegs;i++)
if(i != owningIndex && i != containingIndex)
{
bufferIndex = i;
break;
}
if(containingIndex>= 0 && owningIndex != containingIndex)
move(plate, owningIndex, containingIndex, bufferIndex);
}
}
void HanoiWithStatus::MoveToFinal()
{
int maxPlate = - 1;
for( int i= 0 ;i<m_pegs;i++)
{
if(InitialPegStatus[i].size()> 0)
{
maxPlate = InitialPegStatus[i].back();
break;
}
}
for( int i = maxPlate;i>= 0;i--)
{
cout<< " Moving "<<i<<endl;
MoveOnePlateToTarget(i);
}
}
void HanoiWithStatus::MoveOnePlateToTarget( int plate)
{
int owningIndex = - 1, finalIndex = - 1;
int bufferIndex = - 1;
for( int i= 0;i<m_pegs;i++)
{
list< int>::iterator itr = find(InitialPegStatus[i].begin(), InitialPegStatus[i].end(), plate);
if(itr == InitialPegStatus[i].end())
continue;
else
{
owningIndex = i;
break;
}
}
if(owningIndex >= 0)
{
for( int i= 0;i<m_pegs;i++)
{
list< int>::iterator itr = find(FinalPegStatus[i].begin(), FinalPegStatus[i].end(), plate);
if(itr == FinalPegStatus[i].end())
continue;
else
{
finalIndex = i;
break;
}
}
for( int i = 0;i<m_pegs;i++)
{
list< int>::iterator itr = InitialPegStatus[i].begin();
if(itr == InitialPegStatus[i].end() || *itr >plate)
{
bufferIndex = i;
break;
}
}
if(finalIndex>= 0 && owningIndex != finalIndex)
move(plate, owningIndex, finalIndex, bufferIndex);
}
}
void HanoiWithStatus::Move()
{
Rearrange();
MoveToFinal();
}
int main( int argc, char **argv)
{
HanoiWithStatus* hanoi = new HanoiWithStatus( 4);
hanoi->InitialPegStatus[ 0].push_front( 6);
hanoi->InitialPegStatus[ 0].push_front( 5);
hanoi->InitialPegStatus[ 1].push_front( 3);
hanoi->InitialPegStatus[ 2].push_front( 4);
hanoi->InitialPegStatus[ 3].push_front( 2);
hanoi->InitialPegStatus[ 3].push_front( 1);
hanoi->InitialPegStatus[ 3].push_front( 0);
hanoi->FinalPegStatus[ 3].push_front( 6);
hanoi->FinalPegStatus[ 3].push_front( 5);
hanoi->FinalPegStatus[ 3].push_front( 4);
hanoi->FinalPegStatus[ 3].push_front( 3);
hanoi->FinalPegStatus[ 3].push_front( 2);
hanoi->FinalPegStatus[ 3].push_front( 1);
hanoi->FinalPegStatus[ 3].push_front( 0);
hanoi->Move();
}
#include <list>
#include <stack>
#include <algorithm>
using namespace std;
class HanoiWithStatus
{
public:
HanoiWithStatus( int n)
{
m_pegs = n;
InitialPegStatus = new list< int>[n];
FinalPegStatus = new list< int>[n];
}
void Rearrange();
void MoveToFinal();
void MoveToContainer( int i);
void Move();
list< int>* InitialPegStatus;
list< int>* FinalPegStatus;
void move( int i, int src, int dest, int buffer);
void MoveOnePlateToTarget( int plate);
private:
int m_pegs;
int m_plates;
};
void HanoiWithStatus::Rearrange()
{
m_plates = 0;
for( int i= 0;i<m_pegs;i++)
m_plates +=InitialPegStatus[i].size();
for ( int i= 0 ;i<m_plates;i++)
{
cout<< " Arranging "<<i<<endl;
MoveToContainer(i);
}
for ( int i= 0 ;i<m_pegs;i++)
cout<<InitialPegStatus[i].size()<<endl;
}
void HanoiWithStatus::move( int i, int src, int dest, int buffer)
{
if(i>= 0)
{
move(i- 1, src, buffer, dest);
InitialPegStatus[src].remove(i);
InitialPegStatus[dest].push_front(i);
cout<< " Move "<<i<< " from "<<src<< " to "<<dest<<endl;
move(i- 1, buffer, dest, src);
}
}
void HanoiWithStatus::MoveToContainer( int plate)
{
int owningIndex = - 1, containingIndex = - 1;
int bufferIndex = - 1;
for( int i= 0;i<m_pegs;i++)
{
list< int>::iterator itr = find(InitialPegStatus[i].begin(), InitialPegStatus[i].end(), plate);
if(itr == InitialPegStatus[i].end())
continue;
else{
owningIndex = i;
break;
}
}
if(owningIndex >= 0)
{
for( int i= 0;i<m_pegs;i++)
{
list< int>::iterator itr = find(InitialPegStatus[i].begin(), InitialPegStatus[i].end(), plate+ 1);
if(itr == InitialPegStatus[i].end())
continue;
else{
containingIndex = i;
break;
}
}
for( int i = 0;i<m_pegs;i++)
if(i != owningIndex && i != containingIndex)
{
bufferIndex = i;
break;
}
if(containingIndex>= 0 && owningIndex != containingIndex)
move(plate, owningIndex, containingIndex, bufferIndex);
}
}
void HanoiWithStatus::MoveToFinal()
{
int maxPlate = - 1;
for( int i= 0 ;i<m_pegs;i++)
{
if(InitialPegStatus[i].size()> 0)
{
maxPlate = InitialPegStatus[i].back();
break;
}
}
for( int i = maxPlate;i>= 0;i--)
{
cout<< " Moving "<<i<<endl;
MoveOnePlateToTarget(i);
}
}
void HanoiWithStatus::MoveOnePlateToTarget( int plate)
{
int owningIndex = - 1, finalIndex = - 1;
int bufferIndex = - 1;
for( int i= 0;i<m_pegs;i++)
{
list< int>::iterator itr = find(InitialPegStatus[i].begin(), InitialPegStatus[i].end(), plate);
if(itr == InitialPegStatus[i].end())
continue;
else
{
owningIndex = i;
break;
}
}
if(owningIndex >= 0)
{
for( int i= 0;i<m_pegs;i++)
{
list< int>::iterator itr = find(FinalPegStatus[i].begin(), FinalPegStatus[i].end(), plate);
if(itr == FinalPegStatus[i].end())
continue;
else
{
finalIndex = i;
break;
}
}
for( int i = 0;i<m_pegs;i++)
{
list< int>::iterator itr = InitialPegStatus[i].begin();
if(itr == InitialPegStatus[i].end() || *itr >plate)
{
bufferIndex = i;
break;
}
}
if(finalIndex>= 0 && owningIndex != finalIndex)
move(plate, owningIndex, finalIndex, bufferIndex);
}
}
void HanoiWithStatus::Move()
{
Rearrange();
MoveToFinal();
}
int main( int argc, char **argv)
{
HanoiWithStatus* hanoi = new HanoiWithStatus( 4);
hanoi->InitialPegStatus[ 0].push_front( 6);
hanoi->InitialPegStatus[ 0].push_front( 5);
hanoi->InitialPegStatus[ 1].push_front( 3);
hanoi->InitialPegStatus[ 2].push_front( 4);
hanoi->InitialPegStatus[ 3].push_front( 2);
hanoi->InitialPegStatus[ 3].push_front( 1);
hanoi->InitialPegStatus[ 3].push_front( 0);
hanoi->FinalPegStatus[ 3].push_front( 6);
hanoi->FinalPegStatus[ 3].push_front( 5);
hanoi->FinalPegStatus[ 3].push_front( 4);
hanoi->FinalPegStatus[ 3].push_front( 3);
hanoi->FinalPegStatus[ 3].push_front( 2);
hanoi->FinalPegStatus[ 3].push_front( 1);
hanoi->FinalPegStatus[ 3].push_front( 0);
hanoi->Move();
}