N-Queens算法。 Plot Twist:女王也是骑士

时间:2017-01-18 22:34:11

标签: c# algorithm recursion

尝试在N-Queens板上修改骑士运动集的N*N算法。在我的情况下,我在4*48*8板上测试它。

我的算法,分别是我的递归无法处理Knight,因为它有时需要跳过一行。如果它只是一个皇后区的动作,则不需要跳过行,因为每行只有1皇后。

问题出在我的Solve()函数中,因为我的递归与Queens的数量有关。通常,每块板的皇后数应为8。但是,结合骑士的动作会将数量减少到6。因此,我认为,递归不够深(只有6行,而不是8行)

例如,4*4电路板上的解决方案是(1,1)(4,2) (行* col)。但它无法跳过第2和第3行。

如何在能够跳过某些行的同时使递归遍历所有行。

    static int[] board = new int[9];
    static int cnt = 0;

    static bool CanPlace(int row, int col) // eg. x[1] = 2, 1st row 2nd col has a Queen
    {            
        for (int j = 1; j <= (row - 1); j++)
        {               
            if (board[j] == col || Math.Abs(board[j] - col) == Math.Abs(j - row)) return false;
            if ((Math.Abs(board[j] - col) - 1)  ==  Math.Abs(j - row)) return false;                
            //The line of code above should work for all of the possible moves of the Knight. 
            //At least it does for a 4x4 board, for the first two lines. 
            //Giving a pair of results = (1,1)(2,4) and the mirror (1,4)(2,1)
        }
        return true;
    }

    static void Solve(int row, int boardSize)
    {
        for (int col = 1; col <= boardSize; col++)
        {
            if (CanPlace(row, col)) //This only triggers 6 times per board
            {
                board[row] = col;
                if (row == boardSize - 2)   // Here i tried to fix it but the bottom rows get sacrificed               
                    PrintBoard();                   
                else
                    Solve(row + 1, boardSize);                   
            }                    
        }        
    }

    static void PrintBoard()
    {
        Console.WriteLine();           
        cnt++;
        for (int i = 1; i <= board.Length-1; i++)
        {
            for (int j = 1; j <= board.Length - 1; j++)               
                if (board[i] == j) Console.Write("Q");                   
                else Console.Write(".");                    
            Console.WriteLine();
        }

        for (int i = 1; i <= board.Length - 1; i++)            
            Console.Write("{0},", board[i]);               

        Console.WriteLine();
    }

    static void Main(string[] args)
    {
        Solve(1, 8);
        Console.WriteLine("\nNumber of solutions: {0}\n",cnt);
    }

1 个答案:

答案 0 :(得分:0)

是的,这变得更难了。您需要对早期问题进行一些修改,这使得这是一个值得编程的练习。

  1. 保持你已经放置了多少个皇后的数量。
  2. 允许跳过一排:不放置女王不是失败;你只是不更新​​计数。
  3. 你需要保留到目前为止找到的最佳解决方案(最大数量的皇后),并继续运行,直到你将第一个女王跑过中途点。
  4. 请注意,必须允许第一行中没有女王。如果在第一行中有一个没有任何皇后的解决方案,那么有一个相应的解决方案,只有一个皇后,只移动了一行。

    这足以让你感动吗?