八皇后问题
题目:在 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;
}
博客持续更新中,欢迎留言