C#中八皇后問題的遞歸解法——N皇后


百度測試部2015年10月份的面試題之——八皇后。

八皇后問題的介紹在此。以下是用遞歸思想實現八皇后-N皇后。

代碼如下:

using System;using System.Collections.Generic;

namespace QueensSolution
{
    class Program
    {
        static int count = 0;
        static void Main(string[] args)
        {
            int n = Int32.Parse(Console.ReadLine());
            List<int> queen = new List<int>(n);
            for (int i = 1; i <= n; i++)
            {
                queen.Add(0);
            }
            PutQueen(n, queen, 0);
            Console.WriteLine(count);
            Console.ReadKey();
        }

        private static void PutQueen(int n, List<int> queen, int row)
        {
            for (queen[row] = 1; queen[row] <= n; queen[row]++)
            {
                if (CheckQueens(queen, row))
                {
                    row++;
                    if (row < n)
                    {
                        PutQueen(n, queen, row);
                    }
                    else
                    {
                        count++;
                        for (int i = 0; i < n; i++)
                        {
                            Console.Write(queen[i].ToString() + " ");
                        }
                        Console.WriteLine();
                    }
                    row--;
                }
            }
        }

        private static bool CheckQueens(List<int> queen, int row)
        {
            for (int i = 0; i < row; i++)
            {
                if (Math.Abs(queen[i] - queen[row]) == Math.Abs(i - row) || queen[i] == queen[row])
                {
                    return false;
                }
            }
            return true;
        }
    }
}

解釋:

1.要想解出在n*n的棋盤上到底有多少種放置皇后的方法,主要用到兩個方法,放皇后的PutQueen方法,檢查皇后的CheckQueens方法。

2.在Main函數里對動態數組進行初始化,這個動態數組用來記錄N皇后中每一行所放置的皇后的位置(1就代表放置在該行第一列,n就代表放置在該行的第n列)。

3.row代表的是八皇后棋盤的每一行。

4.在Main函數中對動態數組進行了一下初始化,這一步是必須的,否則運行結果報錯。

5.變量count(解的個數)聲明在Main函數外,是靜態的。

6.PutQueen方法采用遞歸思想——放皇后(該行中每一列都要放置),檢查放皇后的位置是否合理,如果合理則到下一行,判斷下一行是否存在,如果存在——放皇后(該行中每一列都要放置),檢查放皇后的位置是否合理,如果合理則……直到不存在下一行為止每一行都已經放置好了皇后,這時我們將解的個數記錄一下(count++),然后打印該種解法。

7.在遞歸結束后,一定要記得返回到上一行(row--),這樣才能讓“for (queen[row] = 1; queen[row] <= n; queen[row]++)”生效,實現每一行中的每一列都放置過皇后。一定要注意row--的位置要放在整個if-else語句塊的后面!因為整個if-else語句塊形成了對遞歸過程中狀態的判斷,有兩種狀態,第一種狀態是皇后當前在第2到n-1行,這時候如果想返回上一行,“row--”的位置其實可以寫在if語句塊中"PutQueen(n, queen, row);"這一句的后面;第二種狀態是皇后當前在最后一行(也就是第n行),這時候如果想返回上一行,“row--”的位置其實可以寫在else語句塊中。因此,我們才將“row--”的位置移到了整個if-else語句塊的后面。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM