n皇后问题
前言
在算法设计策略中,采用广度优先产生状态空间树的结点,并使用剪枝函数的方法称为分支限界法。
按照广度优先的原则,一个活结点一旦成为拓展结点(E结点)R后,算法将依次生成他的全部孩子结点,并将他们一一加入活结点表,此时R自身称为死结点。算法从活结点表中另选一个活结点作为E结点。
分支限界法主要分为FIFO分支限界法、LIFO分支限界法和LC分支限界法。
分支限界法主要求解目标和回溯法不一样,他强调 找到满足约束条件的一个解,或是在满足约束条件的解中,找出最优解,他往往解决的是判断 存不存在,有没有 解诸如此类的问题。
一、问题描述
所谓n皇后问题就是求解如何在n×n的棋盘上无冲突的摆放n个皇后棋子。在国际象棋中,皇后的移动方式为横竖交叉的,因此在任意一个皇后所在位置的水平、竖直、以及45度斜线上都不能出现皇后的棋子,例子:
要求编程求出符合要求的情况的个数。
二、使用步骤
1.输入
一个整数,代表n,n不大于10。
2.输出
不产生冲突的所有可行解。
最后一行为所有可行解的个数。
3.测试数据
3.1输入
4
3.1 输出
1 3 0 2
2 0 3 1
2
三.源代码
以下为 分支限界法 的源代码:
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
struct Node{
int k;
int *x;
};
int n,cnt=0;
queue<Node> qu;
int place(int k,int i,int *x){
int j;
for(j=0;j<k;j++){
if(i==x[j]||fabs(k-j)==fabs(i-x[j])) return 0;
}
return 1;
}
void FIFOBB(){
int i,j;
Node nd;
nd.k=0;
nd.x=new int[n+1];
qu.push(nd);
while(!qu.empty()){
nd=qu.front(); qu.pop();
if(nd.k==n){
cnt++;
for(i=1;i<=n;i++) cout<<nd.x[i]<<" "; cout<<endl;
}else{
for(i=0;i<n;i++){
if(place(nd.k+1,i,nd.x)){
Node t;
t.k=nd.k+1;
t.x=new int[n+1];
for(j=0;j<=nd.k;j++) t.x[j]=nd.x[j];
t.x[t.k]=i;
qu.push(t);
}
}
}
}
}
int main(){
cin>>n;
FIFOBB();
cout<<cnt<<endl;
return 0;
}
总结
以上就是今天要讲的内容,喜欢博主那就多读关注啦!!!