百度測試部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語句塊的后面。