八皇后问题

用C#解决八皇后问题

一.引言

首先,我们先了解一下什么是八皇后问题:

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

我们可以思考一下n皇后问题,当然,这里的n需要满足条件n=1或n≥4。

二.工具

已配置好C#实验环境的Visual Studio 2017

三.具体过程

  • 分析

    如果是我们人为地来解决八皇后问题,我们会怎么想呢?大多数人肯定是在第一行第一列的位置放一个皇后,然后移到第二行,从第一列开始判断,发现第一列不可以,移到第二列,也是不可以,然后移到第三列,诶,第三列可以,那放置一个皇后,移到第三行,继续…当我们发现某一行没找到放皇后的位置,那肯定会回到上一行,将上一行的皇后移到目前位置的下一个位置,再去看看下一行是否能放皇后,如果能,移到下一行继续,如果不能,移到上一行继续。

  • 具体代码

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      namespace eightQueens
      {
      	class Program 
      	{
      		static int count = 0;
      		static void Main(string[] args)
     			{
          		int n = Int32.Parse(Console.ReadLine());    //输入n,选择n皇后问题
          		List<int> queen = new List<int>(n);         //创建一个数组
          		for (int i = 1; i <= n; i++)                //数组初始化
          			queen.Add(0);
          		PutQueen(n, queen, 0);                
          		Console.WriteLine(count);
          		Console.ReadKey();
      		}
      		private static void PutQueen(int n, List<int> queen, int row)                //在某个位置放置皇后
      		{
          		for (queen[row] = 1; queen[row] <= n; queen[row]++)
          		{
              		if (CheckQueens(queen, row))
              		{
                  		row++;
                  		if (row < n)
                  			PutQueen(n, queen, row);
                  		else
                  		{
                      		count++;
                      		for (int i = 0; i < n; i++)
                      			Console.Write(queen[i].ToString() + " ");
                      		Console.WriteLine();
                  		}
                  		row--;
              		}
          		}
      		}
      		private static bool CheckQueens(List<int> queen, int row)   //判断某个位置是否可以放置八皇后
     			{
          		for (int i = 0; i < row; i++)
          		{
              		if (Math.Abs(queen[i] - queen[row]) == Math.Abs(i - row) || queen[i] == queen[row])
              		return false;
          		}
          		return true;
     	 		}
      	}
      }
    
  • 代码分析

count为解法数。

先创建一个长度为8的数组,数组第一位隐式表示第一行,存储的数字表示第几列。放置的皇后位置信息可以通过数组元素确定,例如queen[2]=6表示皇后放在第二行第六列。

代码中主要用到两个函数–PutQueen和CheckQueens。函数CheckQueens主要判断该位置的皇后与已放置的皇后是否冲突;函数PutQueen主要是放置皇后,从第一行的第一列开始,经函数CheckQueens判断后表明该位置可以放置,然后判断是否还有下一行,如果有则移到下一行的第一列继续判断,如果没有表示已到最后一行,皇后放置结束,输出结果,然后退回到上一行的下一列继续判断。

  • 结果截图代码截图
    结果截图
    八皇后问题一共有92种解法。

四.总结

本篇文章介绍了在C#中用递归法解决皇后问题。思想要点为判断每一个位置是否可以放置皇后。

用回溯法解决八皇后问题(C++版)

9/28/2018 4:33:28 PM

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值