📜  根据给定条件遍历矩阵的方法数量

📅  最后修改于: 2021-04-29 01:04:07             🧑  作者: Mango

给定一个表示N x N方阵的整数N ,任务是按照以下条件打印从方阵左上角到右下角的移动方式:

  • 如果指针的当前位置在方阵的边缘,则下一个移动可以是垂直移动或水平移动,可以执行任意数量的步长(如棋盘上的车子)。
  • 如果指针的当前位置在方矩阵的对角线上,则下一个移动也应位于对角线上。 (就像主教在棋盘上一样)。
  • 如果指针的当前位置在上述两个位置之外的任何其他位置,则下一步可能会以任何方式进行,例如骑士在棋盘上移动,但是新位置的行和列>旧位置的行和列位置。

例子:

方法:想法是在每种可能的情况下递归检查其是否到达平方矩阵的末尾。为此,定义了一个递归函数,该函数将当前位置和最后一个位置作为输入参数。以下是递归函数的条件:

  • 基本情况:函数的基本情况是检查当前指针是否已到达方阵中的右下角位置。如果达到,则增加记下总数的计数器的计数。如果无法到达最后一个位置,则应停止该函数,并且不应在下一次迭代中调用该函数。这是通过以下方式实现的:
if (cr == er && cc == ec) {
    count++;
    return;
}

if (cr > er || cc > ec) {
   return;
}
  • 递归的情况:考虑到三种类型的遍历是可能的。因此,递归的情况是通过检查当前位置是否递归调用该函数。如果当前位置在方矩阵的边缘,则指针只能水平或垂直移动。对于随后的每个垂直遍历,还可以选择水平和垂直遍历的两种选择。因此,为了跟踪方法的总数,在循环中以递归方式调用了这两种方法。
for (int i = 1; i <= er; i++) {
    if (cc == 0 || cr == 0 
       || cr == er || cc == ec) {
        chessboard1(cr, cc + i, er, ec);
    }
}

for (int i = 1; i <= er; i++) {
    if (cc == 0 || cr == 0 
       || cr == er || cc == ec) {
        chessboard1(cr + i, cc, er, ec);
    }
}
  • 除此之外,如果当前指针在对角线上,则指针可以沿对角线移动。然而,对于每个随后的对角线遍历,另一组后续的对角线是可能的。因此,为了跟踪方法的总数,使用了for循环来递归调用该函数。
for (int i = 1; i <= er; i++) {
    if (cr == cc || cr + cc == er) {
        chessboard1(cr + i, cc + i,
                    er, ec);
    }
}
  • 如果以上情况都不满足,则可以这样移动下一个位置:
    • 新行是>旧行。
    • 新列>旧列。
  • 执行完上述函数,存储在count变量中的值就是遍历平方矩阵的方式总数。

下面是上述方法的实现:

C++
// C++ program to count the number
// of ways to traverse the given
// N x N Square Matrix recursively
#include
using namespace std;
   
// Variable to store the
// total number of ways to
// traverse the Square Matrix
     
// Function to recursively
// count the total number
// of ways to traverse the
// given N x N Square Matrix
void chessboard1(int cr, int cc,
                 int er, int ec,
                 int& count)
{
 
  // If the last index has been
  // reached, then the count is
  // incremented and returned
  if (cr == er && cc == ec)
  {
    count++;
    return;
  }
 
  // If the last index cannot
  // be reached
  if (cr > er || cc > ec)
  {
    return;
  }
 
  // If the current position is
  // neither on the edges nor
  // on the diagonal, then the
  // pointer moves like a knight
  chessboard1(cr + 2, cc + 1,
              er, ec,count);
  chessboard1(cr + 1, cc + 2,
              er, ec,count);
 
  // If the pointer is on the
  // edges of the Square Matrix
  // next move can be horizontal
  // or vertical
 
  // This for loop is used to include
  // all the horizontal traversal cases
  // recursively
  for (int i = 1; i <= er; i++)
  {
    if (cc == 0 || cr == 0||
        cr == er || cc == ec)
    {
      chessboard1(cr, cc + i,
                  er, ec,count);
    }
  }
 
  // This for loop is used to include
  // all the vertical traversal cases
  // recursively
  for (int i = 1; i <= er; i++)
  {
    if (cc == 0 || cr == 0||
        cr == er || cc == ec)
    {
      chessboard1(cr + i, cc,
                  er, ec,count);
    }
  }
 
  // If the pointer is on the
  // diagonal of the Square Matrix
  // next move is also diagonal.
  // For loop is used to include
  // all the diagonal traversal cases.
  for (int i = 1; i <= er; i++)
  {
    if (cr == cc || cr + cc == er)
    {
      chessboard1(cr + i,  cc + i, 
                  er, ec, count);
    }
  }
}
   
// Driver code
int main()
{
  int N = 3;
  int count=0;
  chessboard1(0, 0, N - 1, N - 1,count);
  cout<


Java
// Java program to count the number
// of ways to traverse the given
// N x N Square Matrix recursively
 
public class GFG {
 
    // Variable to store the total number
    // of ways to traverse the Square Matrix
    static int count = 0;
 
    // Function to recursively
    // count the total number
    // of ways to traverse the
    // given N x N Square Matrix
    public static void chessboard1(
        int cr, int cc,
        int er, int ec)
    {
 
        // If the last index has been reached, then
        // the count is incremented and returned
        if (cr == er && cc == ec) {
            count++;
            return;
        }
 
        // If the last index cannot be reached
        if (cr > er || cc > ec) {
            return;
        }
 
        // If the current position is neither
        // on the edges nor on the diagonal,
        // then the pointer moves
        // like a knight
        chessboard1(cr + 2, cc + 1, er, ec);
        chessboard1(cr + 1, cc + 2, er, ec);
 
        // If the pointer is on the
        // edges of the Square Matrix
        // next move can be horizontal or vertical
 
        // This for loop is used to include all the
        // horizontal traversal cases recursively
        for (int i = 1; i <= er; i++) {
            if (cc == 0 || cr == 0
                || cr == er || cc == ec) {
                chessboard1(cr, cc + i, er, ec);
            }
        }
 
        // This for loop is used to include all the
        // vertical traversal cases recursively
        for (int i = 1; i <= er; i++) {
            if (cc == 0 || cr == 0
                || cr == er || cc == ec) {
                chessboard1(cr + i, cc, er, ec);
            }
        }
 
        // If the pointer is on the
        // diagonal of the Square Matrix
        // next move is also diagonal.
        // For loop is used to include
        // all the diagonal traversal cases.
        for (int i = 1; i <= er; i++) {
            if (cr == cc
                || cr + cc == er) {
 
                chessboard1(cr + i,
                            cc + i,
                            er, ec);
            }
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        int N = 3;
        chessboard1(0, 0, N - 1, N - 1);
        System.out.println(count);
    }
}


C#
// C# program to count the number
// of ways to traverse the given
// N x N Square Matrix recursively
using System;
 
class GFG{
 
// Variable to store the total number
// of ways to traverse the Square Matrix
static int count = 0;
 
// Function to recursively
// count the total number
// of ways to traverse the
// given N x N Square Matrix
public static void chessboard1(int cr, int cc,
                               int er, int ec)
{
     
    // If the last index has been reached, then
    // the count is incremented and returned
    if (cr == er && cc == ec)
    {
        count++;
        return;
    }
 
    // If the last index cannot be reached
    if (cr > er || cc > ec)
    {
        return;
    }
 
    // If the current position is neither
    // on the edges nor on the diagonal,
    // then the pointer moves
    // like a knight
    chessboard1(cr + 2, cc + 1, er, ec);
    chessboard1(cr + 1, cc + 2, er, ec);
 
    // If the pointer is on the edges
    // of the Square Matrix next move
    // can be horizontal or vertical
 
    // This for loop is used to include all the
    // horizontal traversal cases recursively
    for(int i = 1; i <= er; i++)
    {
        if (cc == 0 || cr == 0 ||
           cr == er || cc == ec)
        {
            chessboard1(cr, cc + i, er, ec);
        }
    }
     
    // This for loop is used to include all the
    // vertical traversal cases recursively
    for(int i = 1; i <= er; i++)
    {
        if (cc == 0 || cr == 0 ||
           cr == er || cc == ec)
        {
            chessboard1(cr + i, cc, er, ec);
        }
    }
     
    // If the pointer is on the
    // diagonal of the Square Matrix
    // next move is also diagonal.
    // For loop is used to include
    // all the diagonal traversal cases.
    for(int i = 1; i <= er; i++)
    {
        if (cr == cc || cr + cc == er)
        {
            chessboard1(cr + i, cc + i,
                        er, ec);
        }
    }
}
 
// Driver code
public static void Main(string[] args)
{
    int N = 3;
     
    chessboard1(0, 0, N - 1, N - 1);
     
    Console.Write(count);
}
}
 
// This code is contributed by rutvik_56


输出 :

18