回溯法求解n皇后問題

皇后問題:

由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);
}



發佈了33 篇原創文章 · 獲贊 15 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章