先上代码,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是一维数组,行只有一个
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)//这句话意思,已经尝试到最后一行了,并且前面的都是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('■');//一行一行的把皇后放进去
else strRow.Add('□');
string tmp = vectorcharTostring(strRow);
item.Add(tmp);
}
res.Add(item);//存储完毕
return;
}
for (int i = 0; i < n; i++)//回朔法的关键,在于多次回调
{
colForrow[row] = i;
if (checkValidQueen(row, colForrow))
helper_queen(n, row + 1, colForrow, res);//只有前一行测试好了,才会进入下一行查看的。注意那个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();
}
}