八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。
问题的内容是在国际象棋棋盘上(8*8),放置八个皇后并使其不能互相攻击。
核心在于皇后的规则:任意两个皇后都不能处于同一行、同一列或同一斜线上。
之前写过一次八皇后算法以实现功能为目标,故而显得代码冗杂而可读性低,此次将主要代码限制在20行。
重写前的算法
想法依旧是通过递归行的方式来解决问题:
第一行取八个不同的皇后位置,并依次向下递归调用第二行(即每个位置取一次)
第二行也取八个不同的皇后位置,并判断是否满足不能互相攻击的原则,满足的再次向下递归调用第三行
直到最后一行处理,满足条件的取出来即八皇后问题的解法。
使用C#实现的效果:
接下来是用C#实现的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace test {
class Program {
const int COUNT = 8;
static int anser = 0;
static void Main(string[] args) {
Search(0, new List<int>(), new List<int>());
Console.WriteLine("八皇后问题的解法有: " + anser + " 种。");
Console.ReadLine();
}
static void Search(int line, List<int> x, List<int> y) {
for (int i = 0; i < COUNT; i++) {
for (int c = 0,r = 0; c < x.Count + (x.Count == 0 ? 1 : 0); c++) { //只判断y -- 用List.foreach
if (x.Count != 0 && i != y[c] && Math.Abs(x[c] - line) != Math.Abs(y[c] - i)) {
r++; //要判断结果集x,y中的每一个,都符合才行
}
if (r == y.Count && r == 7)
anser++;
if (y.Count == 0 ||r == y.Count && r != 7) {
List<int> tx = x.ToList(); List<int> ty = y.ToList();
tx.Add(line); ty.Add(i);
Search(line + 1, tx, ty);
}
}
}
}
}
}