當前位置:首頁 » 操作系統 » n皇後問題演算法

n皇後問題演算法

發布時間: 2024-04-16 17:42:47

c語言 N皇後問題

q[j] == i表示與上個棋子同列(同行是不可能,不用考慮),還有情況得舍棄的就是斜線,左斜和右斜,)(abs(q[j]-i)==(abs(j-k))))這個就表示與前面的棋子是否在同一斜線,左斜右斜都包括了,你自己寫寫就能總結出這個式子了,數學計算而已。不懂HI我

⑵ n皇後問題,遞歸演算法

c:

#include<stdio.h>
#include<stdlib.h>
intresult=0;
voidqueen(int*chess,intlen,intn){
if(n==len){
result++;
}else{
intflag=0;
for(inti=0;i<len;i++){
flag=1;
for(intj=0;j<n;j++){
if(abs(n-j)==abs(i-chess[j])||chess[j]==i){
flag=0;
break;
}
}
if(!flag)
continue;
chess[n]=i;
queen(chess,len,n+1);
chess[n]=0;
}
}
}

intmain(void){
intn;
int*chess;
scanf("%d",&n);
chess=(int*)malloc(sizeof(int)*n);
queen(chess,n,0);
printf("result=%d ",result);
return0;
}

⑶ 演演算法的n 皇後問題是否必然有解,理由是什麼 研究好久到處爬文還是搞不太懂QAQ 謝謝!!

N皇後問題是一個經典的問題,在一個N*N的棋盤上放置N個皇後,每行一個並使其不能互相攻擊(同一行、同一列、同一斜線上的皇後都會自動攻擊)。

一、 求解N皇後問題是演算法中回溯法應用的一個經典案例
回溯演算法也叫試探法,它是一種系統地搜索問題的解的方法。回溯演算法的基本思想是:從一條路往前走,能進則進,不能進則退回來,換一條路再試。
在現實中,有很多問題往往需要我們把其所有可能窮舉出來,然後從中找出滿足某種要求的可能或最優的情況,從而得到整個問題的解。回溯演算法就是解決這種問題的「通用演算法」,有「萬能演算法」之稱。N皇後問題在N增大時就是這樣一個解空間很大的問題,所以比較適合用這種方法求解。這也是N皇後問題的傳統解法,很經典。

下面是演算法的高級偽碼描述,這里用一個N*N的矩陣來存儲棋盤:
1) 演算法開始, 清空棋盤,當前行設為第一行,當前列設為第一列
2) 在當前行,當前列的位置上判斷是否滿足條件(即保證經過這一點的行,列與斜線上都沒有兩個皇後),若不滿足,跳到第4步
3) 在當前位置上滿足條件的情形:
在當前位置放一個皇後,若當前行是最後一行,記錄一個解;
若當前行不是最後一行,當前行設為下一行, 當前列設為當前行的第一個待測位置;
若當前行是最後一行,當前列不是最後一列,當前列設為下一列;
若當前行是最後一行,當前列是最後一列,回溯,即清空當前行及以下各行的棋盤,然後,當前行設為上一行,當前列設為當前行的下一個待測位置;
以上返回到第2步
4) 在當前位置上不滿足條件的情形:
若當前列不是最後一列,當前列設為下一列,返回到第2步;
若當前列是最後一列了,回溯,即,若當前行已經是第一行了,演算法退出,否則,清空當前行及以下各行的棋盤,然後,當前行設為上一行,當前列設為當前行的下一個待測位置,返回到第2步;
演算法的基本原理是上面這個樣子,但不同的是用的數據結構不同,檢查某個位置是否滿足條件的方法也不同。為了提高效率,有各種優化策略,如多線程,多分配內存表示棋盤等。
在具體解決該問題時,可以將其拆分為幾個小問題。首先就是在棋盤上如何判斷兩個皇後是否能夠相互攻擊,在最初接觸這個問題時,首先想到的方法就是把棋盤存儲為一個二維數組,然後在需要在第i行第j列放置皇後時,根據問題的描述,首先判斷是在第i行是否有皇後,由於每行只有一個皇後,這個判斷也可以省略,然後判斷第j列是否有皇後,這個也很簡單,最後需要判斷在同一斜線上是否有皇後,按照該方法需要判斷兩次,正對角線方向和負對角線方向,總體來說也不難。但是寫完之後,總感覺很笨,因為在N皇後問題中這個函數的使用次數太多了,而這樣做效率較差,個人感覺很不爽。上網查看了別人的實現之後大吃一驚,大牛們都是使用一個一維數組來存儲棋盤,在某個位置上是否有皇後可以相互攻擊的判斷也很簡單。具體細節如下:

把棋盤存儲為一個N維數組a[N],數組中第i個元素的值代表第i行的皇後位置,這樣便可以把問題的空間規模壓縮為一維O(N),在判斷是否沖突時也很簡單,首先每行只有一個皇後,且在數組中只佔據一個元素的位置,行沖突就不存在了,其次是列沖突,判斷一下是否有a[i]與當前要放置皇後的列j相等即可。至於斜線沖突,通過觀察可以發現所有在斜線上沖突的皇後的位置都有規律即它們所在的行列互減的絕對值相等,即| row – i | = | col – a[i] | 。這樣某個位置是否可以放置皇後的問題已經解決。

⑷ 演算法 n皇後 求詳細解答

⑸ n皇後問題

輸出結果沒有做什麼處理
直接列印的
以前寫過列印圖形的,懶得搞了

#include <iostream.h>
#include <math.h>

bool Place(int x[],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 0;
return 1;
}

void Output(int n,int x[])
{
cout<<"[";
for(int i=1;i<n;i++)
cout<<x[i]<<",";
cout<<x[n]<<"]"<<endl;
return;
}

void Queue(int n,int x[])
{
int i;
for (i=1;i<=n;i++) //初始化
x[i]=0;
int k=1;
int num=0;
while(k>=1)
{
x[k]=x[k]+1; //在下一列放置第k個皇後
while (x[k]<=n && !Place(x,k))
x[k]=x[k]+1; //搜索下一列
if (x[k]<=n && k==n) { //得到一個解,輸出
Output(n,x);
num++;
}
else if (x[k]<=n && k<n)
k=k+1; //放置下一個皇後
else {
x[k]=0; //重置x[k],回溯
k=k-1;
}
}
}

int main(int argc, char *argv[])
{
cout<<"請輸入皇後的個數\n";
int n;
cin>>n;
int *x=new int[n];
x[0]=0;
Queue(n,x);
return 0;
}

熱點內容
刀劍亂舞掛機腳本 發布:2024-11-27 18:37:56 瀏覽:504
截取字元串java 發布:2024-11-27 18:34:09 瀏覽:331
安卓導航怎麼會黑屏 發布:2024-11-27 18:17:19 瀏覽:394
編譯後代碼放在單片機哪個位置 發布:2024-11-27 18:12:01 瀏覽:458
linux紅帽安裝 發布:2024-11-27 18:01:53 瀏覽:827
手機編程藍牙 發布:2024-11-27 17:55:39 瀏覽:385
創維雲電視怎麼升級安卓系統 發布:2024-11-27 17:55:31 瀏覽:354
theisle游戲伺服器搭建 發布:2024-11-27 17:47:43 瀏覽:210
xshell解壓 發布:2024-11-27 17:35:14 瀏覽:359
ftp伺服器管理方法 發布:2024-11-27 17:24:48 瀏覽:975