先上代碼箭养,C#的:
class Program
{
string vectorcharTostring(List<char> ss)
{
string res = "";
for (int i = 0; i < ss.Count; i++)
res += ss[i];
res += '\0';
return res;
}
bool checkValidQueen(int row, int[] colForrow)
{/*需要檢查三個:1.行是否有兩個糙及。這個無需檢查,因此colForrow是一維數(shù)組尖阔,行只有一個
2.列是否有兩個贮缅。這個只需要查看colForrow是否有相同的元素即可
3.對角線檢查榨咐。對角線也必須沒有相同的兩個。對角線的方法是:就是行的差和列的差的絕對值不要相等就可以*/
for (int i = 0; i < row; i++)
if (colForrow[row] == colForrow[i] || Math.Abs(colForrow[row] - colForrow[i]) == row - i) return false;
return true;
}
void helper_queen(int n, int row, int[] colForrow, List<List<string>> res)
{
if (row == n)//這句話意思谴供,已經(jīng)嘗試到最后一行了块茁,并且前面的都是checkValidQueen()返回true了,那么就得到答案了
{
List<string> item = new List<string>();
for (int i = 0; i < n; i++)
{
List<char> strRow = new List<char>();
for (int j = 0; j < n; j++)
if (colForrow[i] == j) strRow.Add('■');//一行一行的把皇后放進(jìn)去
else strRow.Add('□');
string tmp = vectorcharTostring(strRow);
item.Add(tmp);
}
res.Add(item);//存儲完畢
return;
}
for (int i = 0; i < n; i++)//回朔法的關(guān)鍵桂肌,在于多次回調(diào)
{
colForrow[row] = i;
if (checkValidQueen(row, colForrow))
helper_queen(n, row + 1, colForrow, res);//只有前一行測試好了数焊,才會進(jìn)入下一行查看的。注意那個n崎场,永遠(yuǎn)不變的.只有row在變化的
}
}//逐行求解佩耳,在每一行嘗試每個列位置
List<List<string>> solveNQueens(int n)
{
List<List<string>> res = new List<List<string>>();
int[] colForrow = new int[n];
helper_queen(n, 0, colForrow, res);
return res;
}
static void Main(string[] args)
{
Program Pro = new Program();
//開始求解
List<List<string>> ss = Pro.solveNQueens(4);
foreach (List<string> s in ss)
{
Console.WriteLine();
foreach (string r in s)
{
Console.WriteLine(r);
}
}
Console.WriteLine("over: " + ss.Count);
Console.ReadKey();
}
}