汉诺塔的变形题目:
现在有多个柱子,柱子上有若干盘子,盘子的摆放要求编号小的盘子一定在编号大的盘子的上面。初始时,若干个盘子分散在这些柱子上,要求实现一个算法,将盘子移动到其他柱子上。
这个题目其实并不是很难,但是一定要分析清楚和能够熟练使用递归算法。
#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();
}