日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

八皇后问题(回溯法)

發(fā)布時(shí)間:2023/11/29 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 八皇后问题(回溯法) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

#include<iostream> using namespace std; #define N 8 //N代表皇后數(shù) void queen() { int Count=0; //計(jì)算總共的解的數(shù)量 int column[N+1]; //column[m]=n表示第m行,第n行放置了皇后,這里下表并從0開始 int row[N+1]; //row[m]=1表示第m行沒有皇后,=0表示有皇后 int b[2*N+1]; //b[m]=1表示第m條主對(duì)角線沒有皇后, int c[2*N+1]; //c[m]=1表示第m條次對(duì)角線沒有皇后,=0表示有皇后 int numQueen=1; //計(jì)數(shù)已經(jīng)放置的皇后數(shù)目,當(dāng)numQueen=N時(shí)候則表示已經(jīng)完成探測(cè) int good=1; //good=1表示沒有發(fā)生沖突,good=0表示發(fā)生沖突 //初始化這些標(biāo)記 for(int j=0;j<N+1;++j) { row[j]=1; } for(int j=0;j<2*N+1;++j) { b[j]=c[j]=1; } column[1]=1; column[0]=0; //初始化第一行第一列,第二行第二列放置皇后 do { //沒有發(fā)生沖突,則繼續(xù)向下探測(cè),增加皇后或者判斷當(dāng)前是否是解 if(good) { //當(dāng)前皇后數(shù)是解,打印,繼續(xù)向下探測(cè) if(numQueen==N) { Count++; cout<<"找到解"<<endl; for(int j=1;j<N+1;++j) { cout<<j<<"列"<<column[j]<<"行"<<endl; } //最后一個(gè)棋子向下移動(dòng),移動(dòng)到本列最后一個(gè) while(column[numQueen]==N) { numQueen--; //皇后數(shù)減1,即列數(shù)減1,回溯 //回溯后將該列以及該列最后一行狀態(tài)位修改 //第numQueen列column[numQueen]行處狀態(tài)位置修改 row[column[numQueen]]=1; b[numQueen+column[numQueen]]=1; c[N+numQueen-column[numQueen]]=1; } column[numQueen]++; //回溯至上一行,向上一行的下一列繼續(xù)探測(cè) } //當(dāng)前不是解,那么繼續(xù)向下探測(cè) else { //改變?cè)撐恢脤?duì)應(yīng)標(biāo)志 row[column[numQueen]]=0; b[numQueen+column[numQueen]]=0; c[N+numQueen-column[numQueen]]=0; //本次位置沒有發(fā)生沖突,也不是正確解,那么就應(yīng)該向下探測(cè)下一列的第一行 column[++numQueen]=1; } } //如果當(dāng)前發(fā)生了沖突,就在本列繼續(xù)向下,如果到了本列最后一行,則回溯到上一列 else { while(column[numQueen]==N) //到了本列最后一行,還是沖突,那么回溯到上一列 { numQueen--; row[column[numQueen]]=1; b[numQueen+column[numQueen]]=1; c[N+numQueen-column[numQueen]]=1; } column[numQueen]++; //發(fā)生沖突了,又沒有到本列的最后一行,那么在本列繼續(xù)向下一行探測(cè) } //檢測(cè)放置了這個(gè)位置后是否沖突 good=row[column[numQueen]]&b[numQueen+column[numQueen]]&c[N+numQueen-column[numQueen]]; }while(numQueen); cout<<N<<"皇后總共找到解:"<<Count<<"個(gè)"<<endl; } void main() { queen(); system("pause"); }

這種非遞歸方法還是比較容易理解的

?

另外還有遞歸方法,先來看一下遞歸算法的偽代碼

void trial(int row)

{

???? //遞歸時(shí)候,我們從第0行開始,然后每次遞歸時(shí)候,都向下一行,一直到棋盤的最后一行

???? //這時(shí)候就表示已經(jīng)是正確的解了,所有進(jìn)入該函數(shù)首先判斷是否是正確的解

???? if(row>N)

??? {

???????? //輸出此時(shí)的棋盤

??? }

????else

??? {

??????? for(int i=0;i<N;++i)

??????? {?

???????????? //不是解,這時(shí)候需要在本行的每一列開始試探放旗子,如果可以的話繼續(xù)向下遞歸

???????????? #修改記錄沖突的數(shù)組

???????????? ?if(放在這個(gè)位置不會(huì)沖突)

???????????? {

???????????????????? trial(row+1);

???????????? }

???????????? 放在這里沖突,那么修改回記錄的數(shù)組,繼續(xù)下一列

??????? }

???? }

}

?

下面給出遞歸的

void EightQueen (int row) { if(row>N) { PrintMap(); //打印棋盤 } else { int column; for (column = 0; column < N; ++column) { A[row]= column; //代表第row行的第column列放皇后 if (IsCorrect (row, column)) //判斷在第row行的第column列放皇后是否可行 { EightQueen (row + 1); } //將標(biāo)記數(shù)組修改回原來 } } }




查看源代碼示例

查看源代碼示例

轉(zhuǎn)載于:https://blog.51cto.com/seanyxie/1375902

總結(jié)

以上是生活随笔為你收集整理的八皇后问题(回溯法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。