著名的八皇后问题大家应该都知道,不过以防万一这里还是再说一下:
八皇后问题是一个以国际象棋为背景的问题其内容为求解如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?即任意两个皇后都不能处于同一条横行、纵行或斜线上。
而N皇后顾名思义就是同样的规则扩展到N个皇后。
在这里给出两种方法:
迭代:
#include <iostream>
#include <cmath>
using namespace std;
const int MAXN = 1005;
int data[MAXN];//存储过程数据
int count;//用于计数
bool check(int K){//检查当前点是否合格
for(int i=1 ; i<K ; i++){
if(data[i] == data[K] || abs(data[i]-data[K]) == K-i)return false;
}
return true;
}
void Queen(int N){
int K = 1;
data[K] = 0;
while(K>0){
++data[K];
for(; data[K]<=N ; ++data[K]){
if(check(K))break;
}
if(data[K]<=N){
if(K == N){//找到解
for(int i=1 ; i<=N ; i++)cout<<data[i];
cout<<endl;
++count;
}else {
++K;
data[K] = 0;//这点一定要记得更新为0,切记切记
}
}else {
--K;
}
}
}
int main(){
int N;
while(cin>>N){
count = 0;
Queen(N);
cout<<count<<endl;
}
return 0;
}
递归(推荐这种方法,容易理解):
#include <iostream>
#include <cmath>
using namespace std;
const int MAXN = 1005;
int data[MAXN];//存储过程数据
int count;//用于计数
bool check(int K){//检查当前点是否合格
for(int i=1 ; i<K ; i++){
if(data[i] == data[K] || abs(data[i]-data[K]) == K-i)return false;
}
return true;
}
void Queen(int N,int K){
if(K > N){//找到解
for(int i=1 ; i<=N ; i++){
cout<<data[i];
}
cout<<endl;
++count;
return;
}else {
for(int i=1 ; i<=N ; i++){
data[K] = i;
if(check(K))Queen(N,K+1);//如果当前点可行开始找下一个点
}
}
}
int main(){
int N;
while(cin>>N){
count = 0;
Queen(N,1);
cout<<count<<endl;
}
return 0;
}
位运算优化版(最快):
#include <bits/stdc++.h>
using namespace std;
int DFS(int l,int r,int c,int index,int n){//l,r,c,表示该行被右上角斜线,左上角斜线,正上方直线所影响而不能摆放的位置。
if(index == n)return 1;
int sum = 0;
for(int i=0 ; i<n ; ++i){
int t = 1<<i;
if(t&l || t&r || t&c)continue;
sum += DFS((l|t)<<1,(r|t)>>1,c|t,index+1,n);
}
return sum;
}
int main(){
int n;
while(cin >> n)
printf("%d\n",DFS(0,0,0,0,n));
return 0;
}