10+行代碼解決八皇后問題

//C語言 遞歸+回溯 八皇后問題
//文末附10+行代碼解決八皇后問題(全排列函數)
/*
chess[8][8]:國際象棋棋盤 (0表示不放皇后,1表示放皇后)
row[8]:棋盤中每一行是否滿足要求(規定row[i]<=0爲滿足要求)
col[8]:棋盤中每一列是否滿足要求(規定col[i]<=0爲滿足要求)
left[15]: 棋盤中每一條左斜線是否滿足要求(規定left[15] <=0爲滿足要求,且左上爲起始)
right[15]:棋盤中每一條右斜線是否滿足要求(規定right[15]<=0爲滿足要求,且右上爲起始)
/
//算法詳解:1.right[i-j+7] 表示在8
8的棋盤中,第i行,第j列所對應的右斜線。(自己畫一畫就瞭然)
#include<stdio.h>
int chess[8][8]={0},row[8]={0},col[8]={0},left[15]={0},right[15]={0};
int ans=0;
int isRight(){ //判斷是否符合要求
int i,j,flag=0;
for(i=0;i<8;i++){
if(row[i]>1||col[i]>1)return 0;
for(j=0;j<8;j++){
if(left[i+j]>1||right[i-j+7]>1){
return 0;
}
}
}
return 1;
}
void dfs(int n){ //傳入的n作棋盤的列
//遞歸出口,當n8表明當前已經試探到棋盤的最後一列
if(n
8){
if(isRight()){
ans++;
printf(“第%d種解法:\n”,ans);
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
printf("%d “,chess[i][j]);
}
printf(”\n");
}
}
return;
}
else{
for(int i=0;i<8;i++){//i作行
chess[i][n]=1;//試探
row[i]++;col[n]++;left[i+n]++;right[i-n+7]++;//看上面解釋
if(isRight())//滿足要求則進行遞歸,否則回溯到前一步
dfs(n+1);
chess[i][n]=0;//回溯
row[i]–;col[n]–;left[i+n]–;right[i-n+7]–;
}

}

}
int main(){
dfs(0);
printf(“共有%d種解法\n”,ans);
return 0;
}
ps:如果只是想求出有多少種解法,大可以直接用一個一維數組代替chess。本程序只爲算法小白理解而生,大佬若有更好算法,可請指教(事實上確實還可以優化一下)
以下利用C++全排列函數輕鬆解決:
#include
#include
#include
using namespace std;
int main(){
int chess[8]={1,2,3,4,5,6,7,8},ans=0,i,j;
do{
int flag=1;
ans++;
for(i=0;i<8&&flag;i++)
for(j=i+1;j<8&&flag;j++)
if(abs(i-j)==abs(chess[i]-chess[j])){
flag=0;ans–;
}
}while(next_permutation(chess,chess+8));
cout<<ans<<endl;
return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章