好久沒寫了,今天網上看到了八皇后問題,看看自己還能想起
八皇后問題,是一個古老而著名的問題,是回溯算法的典型例題。該問題是十九世紀著名的數學家高斯1850年提出:在8X8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法。 高斯認爲有76種方案。1854年在柏林的象棋雜誌上不同的作者發表了40種不同的解,後來有人用圖論的方法解出92種結果。計算機發明後,有多種方法可以解決此問題。(來自百度百科)
思路:
8*8的棋牌上,從第1行開始:
在第1列---第8列的i列放置第一個皇后,
從第2行開始 在已經放置過的列上不能再放置皇后。。。同時在已經放置過皇后的對角線和副對角線都不能放置皇后;
直到第8行上有皇后==》成功放置
用遞歸實現:
從第0行開始的,所以row>=8 是,count++;return
每行都從列0---7,循環判斷
代碼及解釋:
#include<stdio.h>
int col[8],pd[15],nd[15];//col[8]表示第i列上有皇后;pd[15]:row+col的值總是小於等於14即:0--14,在8*8的棋牌上對角線上row+col是常數,所以主對角線上的我們可以用一
//數組來存,pd[15];同理row-col+7也在0--14內也可以用nd[15]來存
int temp[8][8]; //存放每組 皇后
int count;//記錄成次數
void init(){//初始化
int i;
for(i=0;i<8;i++)
col[i]=0;
for(i=0;i<15;i++){
pd[i]=nd[i]=0;
}
for(int j=0;j<8;j++)
for(int t=0;t<8;t++)
temp[j][t]=0;
}
void eightqueen(int row){
if(row>=8){//說明此次放置成功,並輸出
count++;
printf("the %dth\n",count);
for(int j=0;j<8;j++){
for(int t=0;t<8;t++){
printf("%d ",temp[j][t]);
}
printf("\n");
}
printf("\n\n");
return;
}
int i;
for(i=0;i<8;i++){//每行都需要從第0列開始判斷
if(col[i]||pd[row+i]||nd[row-i+7]) continue;//如果本列有皇后,則看下一列
col[i]=pd[row+i]=nd[row-i+7]=1;//放置皇后
temp[row][i]=1;//標誌皇后位置
eightqueen(row+1);//遞歸放置下一行上的位置
col[i]=pd[row+i]=nd[row-i+7]=0;//該列已經探視
temp[row][i]=0;
}
}
int main(){
init();
eightqueen(0);
printf("the count is %d\n",count);
return 0;
}