• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
APS-叶童
博客园    首页    新随笔    联系   管理    订阅  订阅

C#八皇后问题

C#使用递归法求解八皇后问题,看的教程是c语言写的,网上搜了下没有看到免费且能直接参考的例子,求解有92种结果,附上代码给需要的朋友参考。

---------------------------------------------------------------------

八皇后问题(英文:Eight queens),是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。
问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。如果经过±90度、±180度旋转,和对角线对称变换的摆法看成一类,共有42类。计算机发明后,有多种计算机语言可以编程解决此问题。

---------------------------------------------------------------------

求解逻辑整理如下:

1、创建一个二维数组表示棋盘

2、写一个递归函数,传入参数是行数、列数、棋盘。

3、函数内先根据传入的棋盘,新建一个棋盘并且初始化。

4、创建一个全局变量count记录解的数量,初始化为1。

5、递归方法整体思路是根据棋盘一行一行检查。

6、方法内做if分支判断,传入的行数是8的时候,输出棋盘的内容。因为是递归函数,只有计算到最后一次递归函数传入行数是8时,整体开始返回结果,也就是输出结果。输出采用双重for循环,遍历组合成行和列从数组中取值并且输出到控制台。

7、else分支,行数不等于8的时候按传入的行数一列一列的检查棋盘,寻找没有危险的棋子落点。

8、使用if分支,创建一个判断是否有危险的方法,传入行、列、棋盘,假设没有危险,就在这个棋盘位置上赋值1.

9、完成判断是否危险的方法,因为整体逻辑是遍历行的基础上遍历列,所以输入的行方向上没有危险,根据输入的行列位置检查这个位置四个方向和列方向有无危险,有危险即返回false,没有危险即返回true。

10、用数组抽象的棋盘是8*8,左上角原点为[0,0]的一张棋盘,所以落点[x,y]四个方向的坐标分别用[x-1,y-1]、[x+1,y-1]、[x+1,y+1]、[x-1,y+1]来表示。

11、使用for循环遍历的时候需要注意,执行顺序是先执行循环代码再执行表达式3,所以参数初始赋值要注意下,详细解释看下面,

------------------------------------------------------

执行顺序如下
表达式1:初始化(只执行一次)
表达式2:判断条件是否成立
表达式4:循环代码
表达式3:自增语句

for循环的表达式一般如下:

for(表达式1;表达式2;表达式3)

{
表达式4;
}

1 for (int i = 0; i <10; i++)
2 {
3     //循环代码
4 }
5 for (表达式1; 表达式2; 表达式3)
6 {
7     //循环代码
8 }

 

-----------------------------------------------------

八皇后问题递归法代码如下:

using System;

namespace EightQueen
{
    class Program
    {
        static void Main(string[] args)
        {

            int[,] chess = new int[8, 8];
            EightQueen(0, 8, chess);

        }
        static int count = 1;
        static void EightQueen(int row, int n, int[,] chess)
        {
            int[,] chess2 = new int[8, 8];
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    chess2[i, j] = chess[i, j];
                }
            }
            if (8 == row)
            {
                Console.WriteLine();
                Console.WriteLine($"第{count}种");
                Console.WriteLine();
                for (int i = 0; i < 8; i++)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        Console.Write($" {chess2[i, j]}");
                    }
                    Console.WriteLine();
                }
                count++;
            }
            else
            {
                for (int j = 0; j < n; j++)
                {
                    if (NotDanger(row, j, chess))
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            chess2[row, i] = 0;
                        }
                        chess2[row, j] = 1;

                        EightQueen(row + 1, 8, chess2);
                    }
                }
            }

        }
        static bool NotDanger(int row, int j, int[,] chess)
        {
            int i = 0, k = 0;

//判断列方向 for (i = 0; i < 8; i++) { if (chess[i, j] != 0) { return false; } } //判断左上方 for (i = row - 1, k = j - 1; i > -1 && k > -1; --i, --k) { if (chess[i, k] != 0) { return false; } } //判断右上方 for (i = row - 1, k = j + 1; i > -1 && k < 8; --i, ++k) { if (chess[i, k] != 0) { return false; } } //判断左下方 for (i = row + 1, k = j - 1; i < 8 && k > -1; ++i, --k) { if (chess[i, k] != 0) { return false; } } //判断右下方 for (i = row + 1, k = j + 1; i < 8 && k < 8; ++i, ++k) { if (chess[i, k] != 0) { return false; } } return true; } } }

 

posted @ 2021-03-31 15:48  所念所想亦如是  阅读(275)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3