八皇后
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
其实这个问题可以简化一下,如何在8*8的格子里找出8的子格子,使其任意两个格子不在同一行同一列同一个对角线。说白了就是在64个格子里挑出8个格子,如果根据排列组合就会很麻烦,因为限制条件太多。那我们可以转换一下,就是每一行挑一个位置放一个皇后,这样再放另一个皇后的时候就可以只是判断是否在同一列或同一对角线就可以了。这样理论有8!个情况,但是实际少于这些,因为并不是每一种情况我们都进行到底,在运行过程中发现一但不行就可以中断。
代码如下(相关解释在代码里面):
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAXN=8;
//#define MAXN 4
int queen[MAXN],sum=0;/*queen[i]表示第几行*/
void show()
{
for(int i=0;i<MAXN;i++)
cout<<queen[i]<<i<<" ";
cout<<endl;
sum++;
}
int check(int n) /* 检查当前列能否放置皇后 */
{
for(int i=0; i<n;i++)
{
if(queen[i]==queen[n]||abs(queen[i]-queen[n])==(n - i))<span style="font-family: arial, 宋体, sans-serif;">/* 检查竖排和对角线上是否可以放置皇后 */</span>
{
// cout<<"shdafk"<<endl;
return 1;
}
}
// cout<<"shdafk"<<endl;
return 0;
}
void search_queen(int n)
{
for(int i=0;i<MAXN;i++)/*表示第几列,从第0列开始放,每一列都尝试*/
{
queen[n]=i;
if(!check(n))
{
if(n==(MAXN-1))/*如果排完一种就用show函数输出*/
{
show();
}
else
{
search_queen(n+1);/*如果上一行的皇后排好了就拍下一行的皇后*/
// cout<<"dsahfkj"<<endl;
}
}
}
}
int main()
{
search_queen(0);
cout<<sum<<endl;
return 0;
}