八皇后问题

*爱你&永不变心* 提交于 2020-01-22 08:38:29

八皇后问题

题目:在 8×8 的国际象棋棋盘上放置八个皇后,保证任何一个皇后都无法直接吃掉其他的皇后的情况下,即任意两个皇后都不能处于同一条横行、纵行或斜线上。一共有多少中摆放皇后的方法?(92种)

可以利用回溯+递归:有些类似于图的深度搜索,先找到一种方法,再在此方法上一步步回溯。

思路:用数组Queue[]的存储皇后的位置(下标+值),用数组column[]的下标代表是第几列,用column[]数组的值代表此列是否有皇后,用loblique[]和roblique[]存储左斜线和右斜线上是否有皇后;统一:0代表有皇后,1代表无皇后
同一斜列上,行数加列数是同一个常数或行数减列数是一个常数
步骤:1、初始化三个数组
2、for循环
3、递归回溯

#include <iostream>
#include <string.h>
#include <stdio.h>
#define maxnum 8
int coun = 0;  //记录八皇后摆放的方法数
int column[maxnum+1];
int loblique[maxnum*2+1],roblique[maxnum*2+1];
//左斜列i+j从2~16,所以是maxnum*2+1;左斜列i-j从-7~7.
int Queue[maxnum+1];

using namespace std;
void input()
{
    cout<<endl<<"第"<<coun<<"种方法"<<endl;
    for(int i=1;i <= maxnum; i++)
    {
      for(int j=1;j <= maxnum; j++)
      {
          if(Queue[i] == j)
            cout<<"Q";
          else
            cout<<".";
      }
      cout<<endl;
    }
}

void backtrack(int i)
{
    if(i > maxnum)  //找到了一种摆放方法
    {
        coun++;
        input();   //打印
    }
    else
    {
        for(int j=1;j<=maxnum;j++) //列数1~8
        {
            //若此位置列上以及斜列上没有其他皇后
            if(column[j]==1&&loblique[i+j]==1&&roblique[i-j+maxnum]==1)
            {
                //占此位置
                Queue[i]=j;
                column[j] = 0;loblique[i+j]=0;roblique[i-j+maxnum]=0;
                backtrack(i+1); //找第i+1个皇后的位置
                column[j] = 1;loblique[i+j]=1;roblique[i-j+maxnum]=1;
            }
        }
    }
}
int main()
{
    for(int i=1;i<=maxnum;i++)
        column[i]=1;
    for(int i=1;i<=maxnum*2+1;i++)
        roblique[i]=loblique[i]=1;
    backtrack(1);
    cout<<coun;
    return 0;
}

博客持续更新中,若有不断或错误欢迎留言,第二天统一回复,谢谢

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!