汉诺塔 -- 从某个状态移动到另外一个状态

汉诺塔的变形题目:

现在有多个柱子,柱子上有若干盘子,盘子的摆放要求编号小的盘子一定在编号大的盘子的上面。初始时,若干个盘子分散在这些柱子上,要求实现一个算法,将盘子移动到其他柱子上。

这个题目其实并不是很难,但是一定要分析清楚和能够熟练使用递归算法。

 

#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();
}

 

转载于:https://www.cnblogs.com/whyandinside/archive/2012/08/26/2657496.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值