八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。现代教学中,把八皇后问题当成一个经典递归算法例题。
算法分析:数组a、b、c分别用来标记冲突,a数组代表列冲突,从a[0]~a[7]代表第0列到第7列,如果某列上已经有皇后,则为1,否则为0;
数组b代表主对角线冲突,为b[i-j+7],即从b[0]~b[14],如果某条主对角线上已经有皇后,则为1,否则为0;
数组c代表从对角线冲突,为c[i+j],即从c[0]~c[14],如果某条从对角线上已经有皇后,则为1,否则为0;
另优化:第一个皇后在1~4格,最后*2,即为总解数
using System;
class Queen{
const int SIZE = 8;//皇后数
public static void Main()
{
int[] Queen = new int [SIZE];//每行皇后的位置
int y,x,i,j,d,t=0;
y = 0;
Queen[0] = -1;
while( true )
{
for (x=Queen[y]+1; x<SIZE; x++)
{
for (i=0;i<y;i++)
{
j = Queen[i];
d = y-i;
//检查新皇后是否与以前的皇后能相互攻击
if ((j==x)||(j==x-d)||(j==x+d))
break;
}
if (i>=y)
break;//不攻击
}
if (x == SIZE) //没有合适的位置
{
if (0==y)
{
//回朔到了第一行
Console.WriteLine(“Done”);
break; //结束
}
//回朔
Queen[y]=-1;
y–;
}
else
{
Queen[y]=x;//确定皇后的位置
y++;//下一个皇后
if (y<SIZE)
Queen[y]=-1;
else
{
//所有的皇后都排完了,输出
Console.WriteLine(“\n” + ++t +’:’);
for(i=0;i<SIZE;i++)
{
for (j=0;j<SIZE;j++)
if(Queen[i] == j)
Console.Write(‘Q’);
else
Console.Write(‘.’);
Console.WriteLine();
}
y = SIZE -1;//回朔
}
}
}
}
}
八皇后有解92个。
另:我认为foreach和for循环在意义上是不同的,在这里应该用for.
From Baidu Baike
===============================================================================
using System;
using System.Collections.Generic;
using System.Text;
namespace EightQueen
{
class Program
{
class Eight
{
public int[] result = new int[8];
public static int amount = 0;
public void PrintResult()
{
Console.Write(“Result: “);
foreach (int num in result)
{
Console.Write(num.ToString() + ” “);
}
Console.WriteLine(“\n”);
amount++;
}
}
static void PostQueen(ref Eight eig, int row)
{
if (row > 8 || row < 0)
{
return;
}
// the last pst is at row
// 3 Condition: not same row, not same column, not on the bias line
if (row < 7)
{
for (int i = row + 1; i < 8; i++)
{
int tint = eig.result[row] – eig.result;
if (0 == tint || tint == row – i || tint == i – row )
{
// should not be same column
return;
}
}
}
// if at the last Post
if (0 == row)
{
eig.PrintResult();
return;
}
// iterite to post next
for (int i = 0; i < 8; i++)
{
eig.result[row – 1] = i;
PostQueen(ref eig, row – 1);
}
}
static void Main(string[] args)
{
// Eight queen post on 8*8 grid
Eight eig = new Eight();
PostQueen(ref eig, 8);
Console.WriteLine(string.Format(“The total arrange: {0}”, Eight.amount));
Console.Read();
}
}
}