八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
using System; using System.Diagnostics; using System.Linq; namespace 八皇后_回溯算法 { class Program { private static int[,] geizi = new int[8, 8]; private static int[] rowHas = Enumerable.Repeat(-1,8).ToArray(); private static int resultNum = 0; static void Main(string[] args) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); Place(0); stopwatch.Stop(); Console.WriteLine(resultNum + " 用时:" + stopwatch.ElapsedMilliseconds); Console.ReadKey(); } static void Place(int row) { if (row == -1) { return; } int i = 0; int col = -1; int isP = rowHas[row]; if (isP != -1) { //表示这行放过皇后,取消先前放的 geizi[row, isP] = 0; rowHas[row] = -1; } //寻找这行可以放置皇后的地方 for (i = isP + 1; i < 8; i++) { if (col != -1) { continue; } if (CheckPlace(row, i)) { col = i; geizi[row, i] = 1; rowHas[row] = i; } } //判断有没有找到这样的一个位置 if (col != -1) { if (row == 7) { //出结果了,打印结果 PrintAll(); resultNum++; geizi[row, col] = 0; rowHas[row] = -1; Place(row - 1); } else { Place(row + 1); } } else { //没有位置,往上层走,修改上层放置的位置 Place(row - 1); } } //检测是否可以放置 static bool CheckPlace(int row, int col) { //3个方向检测 bool CanPlace = true; for (int i = 0; i < row; i++) { int tRow = row - i - 1; int lCol = col - i - 1; int rCol = col + i + 1; if (tRow < 0) { continue; } //向上 if (geizi[tRow, col] == 1) { CanPlace = false; } //左上 if (lCol >= 0) { if (geizi[tRow, lCol] == 1) { CanPlace = false; } } //右上 if (rCol <= 7) { if (geizi[tRow, rCol] == 1) { CanPlace = false; } } } return CanPlace; } //输出结果 static void PrintAll() { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { Console.Write(geizi[i, j] + " "); } Console.WriteLine(); } Console.WriteLine(); } } }
输出结果有92种,排除输出后用时2-5ms