我与八皇后的恩恩怨怨
什么是八皇后
八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?
高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。(程序跑出来也的确是92种)
八皇后的解法很多
今天,我们只用全排列
代码不长,思路也简单。
首先,八皇后肯定是每行都有,并且都不同列,我们可以通过这个的全排列,来检查是否满足八皇后即可
所以,1,2,3,4,5,6,7,8的全排列,一定是包含了八皇后的解的。
那么我们一一检测就可以得出结果了!
代码如下:
竟然还写的一大会儿,我还是太菜了!
看的人多,我再写其他的解法T.T!!!
#include<iostream>
#include<algorithm>
#include<cstring>
#define mm(a,b) memset(a,b,sizeof(a))
using namespace std;
int ans=0;
void print(int map[][8]){
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
if(map[i][j]==0) cout<<"#"<<" ";
else cout<<"0"<<" ";
}
cout<<endl;
}
}
void search(int map[][8]){
int cntx=0,cnty=0;
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
if(map[i][j]==1) cntx++;
if(map[j][i]==1) cnty++;
if(cntx>1||cnty>1) return ;
}
cntx=0;
cnty=0;
}
for(int i=0;i<8;i++){
int cnt=0;
int j=0;
int tempi=i;
while(tempi<8&&j<8){
if(map[tempi][j]==1) cnt++;
if(cnt>1) return ;
tempi++;
j++;
}
tempi=i,j=0,cnt=0;
while(tempi>=0&&j<8){
if(map[tempi][j]==1) cnt++;
if(cnt>1) return ;
tempi--;
j++;
}
}
for(int j=1;j<8;j++){
int cnt=0;
int i=0;
int tempj=j;
while(i<8&&tempj<8){
if(map[i][tempj]==1) cnt++;
if(cnt>1) return ;
tempj++;
i++;
}
cnt=0,i=7,cnt=0;
tempj=j;
while(i>=0&&tempj<8){
if(map[i][tempj]==1) cnt++;
if(cnt>1) return ;
tempj++;
i--;
}
}
ans++;
cout<<endl<<"第"<<ans<<"种解法:"<<endl;
print(map);
return ;
}
int main(){
int num[8]={1,2,3,4,5,6,7,8};
int map[8][8];
do{
mm(map,0);
for(int i=0;i<8;i++){
map[i][num[i]-1]=1;
}
search(map);
}while(next_permutation(num,num+8));
cout<<"八皇后问题共有"<<ans<<"种解法!"<<endl;
return 0;
}