📜  河内塔|套装2

📅  最后修改于: 2021-05-04 19:47:15             🧑  作者: Mango

给定一个正整数N代表河内塔楼中的磁盘数量,任务是使用二进制表示法解决河内塔楼难题。

例子:

方法:可以根据以下观察结果解决给定问题:

  • 可以看出,移动第N磁盘,第(N – 1)个磁盘 磁盘需要移动。因此,要移动第(N – 1)磁盘,第(N – 2)个磁盘 磁盘需要移动。此过程以递归方式进行。
  • 上面的过程类似于设置最右边的未设置位,因为它需要首先将所有位设置为右边。
  • 因此,该想法是打印所有中间步骤,每次通过将当前数字加1来设置最右边的位。

请按照以下步骤解决问题:

  • 初始化一个大小为N的数组,例如counter [] ,以存储问题的当前状态。
  • 在[0,2 N – 1]范围内进行迭代,设置最右边的未设置位,并取消设置其右边的所有位。
  • 在上述步骤的每次迭代中,将最右边的未设置位的位置打印为要移动的磁盘的编号。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Function to increment binary counter
int increment(int* counter, int n)
{
    int i = 0;
  
    while (true) {
  
        // Stores the Bitwise XOR of
        // the i-th bit of N and 1
        int a = counter[i] ^ 1;
  
        // Stores the Bitwise AND of
        // the i-th bit of N and 1
        int b = counter[i] & 1;
  
        // Swaps the i-th bit of N
        counter[i] = a;
  
        // If b is equal to zero
        if (b == 0)
            break;
  
        // Increment i by 1
        i = i + 1;
    }
  
    // Return i
    return i;
}
  
// Function to print order of movement
// of disks across three rods to place
// all disks on the third rod from the
// first rod
void TowerOfHanoi(int N)
{
    // Stores the binary reprsentation
    // of a state
    int counter[N] = { 0 };
  
    // Traverse the range [0, 2^N - 1]
    for (int step = 1;
         step <= pow(2, N) - 1; step++) {
  
        // Stores the position of the
        // rightmost unset bit
        int x = increment(counter, N) + 1;
  
        // Print the Xth bit
        cout << "Move disk " << x
             << " to next circular"
             << " right rod \n";
    }
}
  
// Driver Code
int main()
{
    int N = 3;
    TowerOfHanoi(N);
  
    return 0;
}


C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Function to print order of movement
// of N disks across three rods to place
// all disks on the third rod from the
// first-rod using binary representation
void TowerOfHanoi(int N)
{
    // Iterate over the range [0, 2^N - 1]
    for (int x = 1;
         x <= pow(2, N) - 1; x++) {
  
        // Print the movement
        // of the current rod
        cout << "Move from Rod "
             << ((x & x - 1) % 3 + 1)
             << " to Rod "
             << (((x | x - 1) + 1) % 3 + 1)
             << endl;
    }
}
  
// Driver Code
int main()
{
    int N = 3;
    TowerOfHanoi(N);
    return 0;
}


输出:
Move disk 1 to next circular right rod 
Move disk 2 to next circular right rod 
Move disk 1 to next circular right rod 
Move disk 3 to next circular right rod 
Move disk 1 to next circular right rod 
Move disk 2 to next circular right rod 
Move disk 1 to next circular right rod

时间复杂度: O(N * 2 N )
辅助空间: O(N)

高效方法:可以基于以下观察条件对上述方法进行优化:对于M范围为[1、2 N – 1]的源棒等于(m&(m – 1))%3 ,而目标棒等于到(m |(m – 1)+1)%3 。因此,想法是在范围内进行迭代 [1,2 N – 1]并将(i&(i – 1))%3的值打印为源棒,并打印(i |(i – 1)+ 1)%3的值作为目标棒。

下面是上述方法的实现:

C++

// C++ program for the above approach
  
#include 
using namespace std;
  
// Function to print order of movement
// of N disks across three rods to place
// all disks on the third rod from the
// first-rod using binary representation
void TowerOfHanoi(int N)
{
    // Iterate over the range [0, 2^N - 1]
    for (int x = 1;
         x <= pow(2, N) - 1; x++) {
  
        // Print the movement
        // of the current rod
        cout << "Move from Rod "
             << ((x & x - 1) % 3 + 1)
             << " to Rod "
             << (((x | x - 1) + 1) % 3 + 1)
             << endl;
    }
}
  
// Driver Code
int main()
{
    int N = 3;
    TowerOfHanoi(N);
    return 0;
}
输出:
Move from Rod 1 to Rod 3
Move from Rod 1 to Rod 2
Move from Rod 3 to Rod 2
Move from Rod 1 to Rod 3
Move from Rod 2 to Rod 1
Move from Rod 2 to Rod 3
Move from Rod 1 to Rod 3

时间复杂度: O(2 N )
辅助空间: O(1)