問題描述:
八皇后問題是十九世紀著名數學家高斯於1850年提出的。問題是:在8*8的棋盤上擺放8個皇后,使其不能互相攻擊,即任意的兩個皇后不能處在同意行,同一列,或同意斜線上。可以把八皇后問題拓展為n皇后問題,即在n*n的棋盤上擺放n個皇后,使其任意兩個皇后都不能處於同一行、同一列或同一斜線上。
問題分析 :
顯然,每一行可以而且必須放一個皇后,所以n皇后問題的解可以用一個n元向量X=(x1,x2,.....xn)表示,其中,1≤ i≤ n且1≤ xi≤ n,即第n個皇后放在第i行第xi列上。
由於兩個皇后不能放在同一列上,所以,解向量X必須滿足的約束條件為:
xi≠ xj;
若兩個皇后的擺放位置分別是(i,xi)和(j,xj),在棋盤上斜率為-1的斜線上,滿足條件i-j=xi-xj;在棋盤上斜率為1的斜線上,滿足條件i+j=xi+xj;
綜合兩種情況,由於兩個皇后不能位於同一斜線上,所以,
解向量X必須滿足的約束條件為:
|i-xi|≠ |j-xj|
代碼如下:哈哈
#include<stdio.h>
#include<math.h>
int x[ 100];
bool place( int k) // 考察皇后k放置在x[k]列是否發生沖突
{
int i;
for(i= 1;i<k;i++)
if(x[k]==x[i]||abs(k-i)==abs(x[k]-x[i]))
return false;
return true;
}
void queue( int n)
{
int i,k;
for(i= 1;i<=n;i++)
x[i]= 0;
k= 1;
while(k>= 1)
{
x[k]=x[k]+ 1; // 在下一列放置第k個皇后
while(x[k]<=n&&!place(k))
x[k]=x[k]+ 1; // 搜索下一列
if(x[k]<=n&&k==n) // 得到一個輸出
{
for(i= 1;i<=n;i++)
printf( " %d ",x[i]);
printf( " \n ");
// return; // 若return則只求出其中一種解,若不return則可以 繼續回溯, 求出全部的可能的解
}
else if(x[k]<=n&&k<n)
k=k+ 1; // 放置下一個皇后
else
{
x[k]= 0; // 重置x[k],回溯
k=k- 1;
}
}
}
void main()
{
int n;
printf( " 輸入皇后個數n:\n ");
scanf( " %d ",&n);
queue(n);
}