皇后問題:
由n*n個方塊排成n行n列的正方形稱爲“n元棋盤”。如果兩個皇后位於棋盤上的同一行或同一列或同一對角線上,則稱她們爲互相攻擊,現要求找使N元棋盤上的n個皇后互不攻擊的所有佈局。
假設棋盤上每一行放置一個皇后,分別用自然數0,1,2,.......,n-1。
首先定義一個長度爲n的一維數組q,其中每一個元素去q[i](i=0,1,2,.......,n-1),隨時記錄第i行皇后所在的列數。
初始時,先將各皇后放在各行的第0列。即數組q的初值爲:q[i]=0, i=0,1,2,.......,n-1
另外第i行與第j行上的皇后在某一對角線上的條件爲去|q[i]-q[j]|=|i-j|;而它們在同一列的條件爲q[i]=q[j];
回溯法算法步驟如下:
對於第i行的皇后,假設前i-1個皇后互相不攻擊,現在來安排第i個皇后使它與前面n-1個皇后互相不攻擊就可以了。
【1】q[i]=n時,表示最後一列也搜索結束,無法安排第i行的皇后,令q[i]=0,回退一行,考慮重新安排第i-1行的皇后,使第i-1行的皇后向右搜索q[i-1]=q[i-1]+1;找到使第i-1行與前i-2行互不攻擊的下一個位置,如果退回到第-1行(實際沒有這一行),表示搜索結束,退出。
【2】當q[i]<n,由於初始q[i]=0;從第0列開始向右搜索,,需要檢查第i行上的皇后與前面的從第0行到第i-1均不互相攻擊,纔算成立,可以考慮下一行的皇后即i=i+1;若不成立,q[i]=q[i]+1,重複前面的步驟。
【3】若安排好了第n-1行的皇后,說明搜索到了一個n皇后互不攻擊的佈局,可將其保存輸出。然後將第n-1行皇后向後移動,即q[n-1]=q[n-1]+1,重複上述步驟,搜索一個皇后佈局。
具體實現代碼
#include "iostream"
#include <cmath>
using namespace std;
bool place(int k,int*q)//考察皇后k放置在x[k]列是否發生衝突
{
int i;
for(i=0;i<k;i++)
if(q[k]==q[i]||abs(k-i)==abs(q[k]-q[i]))
return false;
return true;
}
void n_queen(int n,int*q)
{
int k=0;
while(k>=0)
{
while(q[k]<n&&!place(k,q))
q[k]++;
if(q[k]==n)
{q[k--]=0;q[k]++;}
else
if (k==n-1)
{
for(int i=0;i<n;i++)
cout<<q[i]<<' ';
cout<<endl;
q[k]++;
}
else
{
k++;
}
}
}
void main(void)
{
int n;
cin>>n;
int* q=new int[n];
for(int i=0;i<n;i++)
q[i]=0;
n_queen(n,q);
}