8皇后问题的是一个相当有趣的问题,初看上去,8*8的格子要承受多达8个攻击力如此强大的皇后,谈何容易?
但有趣的地方就在这里,恰恰就能这狭小之地容纳下她们!
一个Q的攻击力是,相关的纵线和横线,以及相关的两条对角线,这是国际象棋中,威力最大的棋子;
应该如何来放下多达8个的这样的Q到一个仅8*8的方阵中呢?(国际象棋的棋盘就是一个8*8的方阵)
如果不为此进行数学方面的考量,单纯的用计算机找的话,那么,算法上来说就只有来,最粗暴的那一种了
下面结合代码简介一下,这样一种粗暴的求解方法:
构造函数如下:
public ComplexionFinder()
{
this.currentColNumer = 0;//即时的列值
this.currentRowNumer = 0;//即时行值
this.findIndex = 0;//初始番动值
this.data = new int[size, size];//8*8的那个棋盘数据阵
this.record = new Point[size];//记录每一个成功放入位置的Q
this.dbx = new DbXml();
}
顶层逻辑:
public void FindAllRightComplexion()//寻找所有正确的局面
{
if (id == null)
id = this;
while (this.findIndex < size)
{
while (this.currentColNumer < size)
{
id.AddQueen();//不断的加入新Q
//this.currentQueenNumer = this.currentColNumer;
}
System.Windows.Forms.MessageBox.Show("找到一个局面");
this.findIndex++;
this.currentColNumer = 0;
this.currentRowNumer = this.findIndex;
id.AddComplexion();
this.ClearData();
this.ResetRecord();
}
id.SaveAllComplexion();
}
加入Q逻辑:
public void AddQueen()
{
this.id.MarkQueenPowerLine();//标注新Q的火力线在data中
//this.id.ResetData();
if (id.CheckIfFullColumn())//判断加入新Q后是否导致了,后面有满值列
{
//回溯
this.ResetData();
id.Remount(id.DistillColumn(this.currentColNumer));//回溯
}
else
{
this.record[this.currentColNumer] = new Point(this.currentRowNumer, this.currentColNumer);//记录当前这个新Q的位置
this.currentColNumer++;//进入下一列
this.id.FindCurrentRowNumer(id.DistillColumn(this.currentColNumer));//为下一列找到第一可加入行值,把它赋给this.currentRowNumber
}
}
代码到这里想必大家经过分析就可以看出来了,这是一种什么解法思想,对,是这样的 以棋盘数据阵的列为顺序,以行为变动适应来搜索的一种方案,因为,任何一个Q不能在同一列,所以先把列固定一来,即要放入8个Q则必然会每一列都仅存在一个Q,同理可知,每一行也仅存在一个Q,如果固定列,那么,行就是变化的,这时按照,列的顺序,以及行的变动来不断检索一个动态维护棋盘数据阵,就可以最终找到所有合乎要求的Q了;
后面还有于回溯的算法,暂时因为没有优化而不做介绍了;