八皇后问题求解-回溯算法

八皇后问题是一个以国际象棋为背景的问题:如何能够在 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


首页 我的博客
粤ICP备17103704号