对于已经放置了k个皇后的给定棋盘,找到N个皇后问题的解决方案

时间:2019-05-18 15:40:37

标签: c# algorithm

这是经典的8个皇后问题,但在这种情况下,将使用N x N板,其中已经放置了一定数量的皇后。您需要填补董事会的其余部分。

样本输入:

.Q..
...Q
....
....

预期产量

.Q..
...Q
Q...
..Q.

下面的代码基于回溯,并且仅在木板为空(即未放置任何皇后)的情况下起作用。如何修改它,以放置未放置的女王/王后不会互相攻击

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;

namespace CSharp_Shell
{

    public static class Program 
    {

        static void printBoard(string [, ] board) {  
            for (int i = 0; i < 4; i++) {  
                for (int j = 0; j < 4; j++) {  
                    Console.Write(board[i, j] + " ");  
                }  
                Console.Write("\n");  
            }  
        }  

        static bool isSafe(string [,] board, int row, int col)
        {
            int i, j;
           for (i = 0; i < col; i++) 
               if (board[row, i] == "Q") 
                   return false; 


            /* Check upper diagonal on left side */
            for (i=row, j=col; i>=0 && j>=0; i--, j--) 
                if (board[i, j]  == "Q") 
                    return false; 

            /* Check lower diagonal on left side */
            for (i=row, j=col; j>=0 && i<4; i++, j--) 
                if (board[i, j] == "Q") 
                    return false;
                return true;
        }
            static bool solve8queen(string[,] board, int col)
            {
                //base case
                if(col >= 4)
                   return true;

                //loop over rows
                for(int row = 0; row < 4; row++)
                {
                    //check if queen can be placed
                    if(isSafe(board, row, col))
                    {
                        //place the queen
                        board[row, col] = "Q";


                        //explore next solution
                        if(solve8queen(board, col + 1))
                           return true;

                        //Backtrack
                        board[row, col] = ".";

                    }


                }

                return false;

            }

        public static void Main()
        {
            string [,] board = {

                           {".", "Q", ".", "."},
                           {".", ".", ".", "Q"},
                           {".", ".", ".", "."},
                           {".", ".", ".", "."}

                         };

            solve8queen(board, 0);
            printBoard(board);

        }


    }
}

1 个答案:

答案 0 :(得分:1)

我相信您可以跳过已经占据女王的列。您还需要修改isSafe()函数以查看整个视图,而不是仅仅放回视图。

因此:

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;

namespace CSharp_Shell
{

    public static class Program
    {

        static void printBoard(string [, ] board) {
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    Console.Write(board[i, j] + " ");
                }
                Console.Write("\n");
            }
        }

        static bool isSafe(string [,] board, int row, int col)
        {
            int i, j;
           /* Check this row completely */
            for (i = 0; i < 4; i++)
                if (board[row, i] == "Q")
                    return false;

            /* Check upper diagonal on left side */
            for (i=row, j=col; i>=0 && j>=0; i--, j--)
                if (board[i, j] == "Q")
                    return false;

            /* Check bottom diagonal on right side */
            for (i=row, j=col; i<4 && j<4; i++, j++)
                if (board[i, j] == "Q")
                    return false;

            /* Check lower diagonal on left side */
            for (i=row, j=col; j>=0 && i<4; i++, j--)
                if (board[i, j] == "Q")
                    return false;

            /* Check upper diagonal on right side */
            for (i=row, j=col; j<4 && i>=0; i--, j++)
                if (board[i, j] == "Q")
                    return false;

                return true;
        }
            static bool solve8queen(string[,] board, int col)
            {
                //base case
                if(col >= 4) {
                    printBoard(board);
                    return true;
                }

                bool res = false;
                //loop over rows
                for(int row = 0; row < 4; row++)
                {
                    //check if queen can be placed
                    if(isSafe(board, row, col))
                    {
                        //place the queen
                        board[row, col] = "Q";



                        // Skip evaluating column 1
                        if(col + 1 == 1)
                            col++;

                        // Skip evaluating column 3
                        if(col + 1 == 3)
                            col++;

                        //explore next solution
                        res = solve8queen(board, col + 1) || res;

                        //Backtrack
                        board[row, col] = ".";

                    }


                }

                return false;

            }

        public static void Main()
        {
            string [,] board = {

                           {".", "Q", ".", "."},
                           {".", ".", ".", "Q"},
                           {".", ".", ".", "."},
                           {".", ".", ".", "."}

                         };

            solve8queen(board, 0);
            //printBoard(board);

        }


    }
}

这将导致以下输出:

. Q . .
. . . Q
Q . . .
. . Q .

另一种可能的方法是修改N皇后问题以打印出所有可能的动作。然后从列表中选择适当的输出。如果没有匹配项,则解决方案不存在。