用递归c++求解10个板的河内塔

Solve Towers of Hanoi with 10 plates recursive c++

本文关键字:内塔 10个 递归 c++ 求解      更新时间:2023-10-16

试图解决河内塔,我真的不明白为什么我的功能不起作用。我已经检查了这里的每个c++解决方案。

bool CPlayer::MoveTop(int n, int from, int to)
{
    if (n == 0)
    {
        m_towers.MoveDisc(to, 1);
        return true;
    }
    MoveTop(n -1 , from , 1);
    m_towers.MoveDisc(1,from);
    MoveTop(n - 1, 1, to);
}// MoveTop

其中1是中间钉。MoveDisc(to,from)将一个圆盘从一个桩移动到另一个桩。

这是对MoveTop函数的第一个调用。

void CPlayer::OnRun()
{
    bool ok = MoveTop(10,0,2);
}// OnRun

我还得到了一个Height函数,它可以返回名为peg的车牌号,但我真的不认为我需要它

添加了更多问题描述所有的移动都显示在一个图形窗口中,在那里我可以看到板块如何从一个桩移动到另一个桩的结果。现在,它不会简单地做它应该做的事情。当运行代码时,第一个平台移动到桩1(中间的桩),并上下"跳跃"。

以下是可用的功能:

高度功能:

int CTowers::Height(int tower)
{
    ASSERT( torn>=0 && torn<3 );
    return m_height[torn];
}

返回特定塔的高度。

int CTowers::TopSize(int tower)
{
        int h = Height(tower);
        if (h==0)
            return 1000;
        else return DiscSize(torn, h-1);
}

返回桩顶的大小。

int CTowers::DiscSize(int tower, int place)
{
    ASSERT( place < Height(torn) );
    return m_pinne[tower][place];
}

返回指定的dicssize。

bool CTowers::MoveDisc(int to, int from)
{
  if (m_abort)
      return false;   //    
  m_pView->DrawAnimation( from, to );
  if (TopSize(from)>=TopSize(to))
        return false;
  m_numMoves++;
  int ds = Pop(from);
  Push(to, ds );
  m_pView->Invalidate();
  return true;
}

将光盘从一个销钉移动到另一个销钉。

这是一个古老的流派:)diver&克服问题。

试试看这个代码:

void hanoi(int diskSize, int source, int dest, int spare)
{
  //This is our standard termination case. We get to here when we are operating on the 
  //smallest possible disk.
  if(diskSize == 0)
    {
        std::cout << "Move disk " << diskSize << " from peg " << source << " to peg " << dest << endl;
    }
    else
    {
        //Move all disks smaller than this one over to the spare.
        //So if diskSize is 5, we move 4 disks to the spare. This leaves us with 1 disk
        //on the source peg.
        //Note the placement of the params.
        //We are now using the dest peg as the spare peg. This causes each recursion to ping-pong
        //the spare and dest pegs.
        hanoi(diskSize - 1, source, spare, dest);
        //Move the remaining disk to the destination peg.
        std::cout << "Move disk "  << diskSize << " from peg " << source << " to peg " << dest << endl;
        //Move the disks we just moved to the spare back over to the dest peg.
        hanoi(diskSize - 1, spare, dest, source);
    }
}

有3个参数(source,dest,spare)的想法是能够在每次都知道哪个peg是空闲的,这样你就可以用它来放置磁盘

如注释中所述,递归ping在备用和dest之间进行。

您的代码不能遵守不能将较大磁盘放在较小磁盘上的规则(请参见此处)。因此,您需要一个变量来保持目标peg,它在代码中并不总是1

这就是为什么你需要3个论点。

干杯!