国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 網(wǎng)站 > 建站經(jīng)驗 > 正文

C#用遞歸算法解決八皇后問題

2019-11-02 13:51:19
字體:
供稿:網(wǎng)友

1.引子

  中國有一句古話,叫做“不撞南墻不回頭",生動的說明了一個人的固執(zhí),有點貶義,但是在軟件編程中,這種思路確是一種解決問題最簡單的算法,它通過一種類似于蠻干的思路,一步一步地往前走,每走一步都更靠近目標(biāo)結(jié)果一些,直到遇到障礙物,我們才考慮往回走。然后再繼續(xù)嘗試向前。通過這樣的波浪式前進(jìn)方法,最終達(dá)到目的地。當(dāng)然整個過程需要很多往返,這樣的前進(jìn)方式,效率比較低下。

2.適用范圍

  適用于那些不存在簡明的數(shù)學(xué)模型以闡明問題的本質(zhì),或者存在數(shù)學(xué)模型,但是難于實現(xiàn)的問題。

3.應(yīng)用場景

  在8*8國際象棋棋盤上,要求在每一行放置一個皇后,且能做到在豎方向,斜方向都沒有沖突。國際象棋的棋盤如下圖所示:

/uploads/cj/201910/201606151029091.jpg

4.分析

  基本思路如上面分析一致,我們采用逐步試探的方式,先從一個方向往前走,能進(jìn)則進(jìn),不能進(jìn)則退,嘗試另外的路徑。首先我們來分析一下國際象棋的規(guī)則,這些規(guī)則能夠限制我們的前進(jìn),也就是我們前進(jìn)途中的障礙物。一個皇后q(x,y)能被滿足以下條件的皇后q(row,col)吃掉

1)x=row(在縱向不能有兩個皇后)

2)y=col(橫向)

3)col + row = y+x;(斜向正方向)

4)col - row = y-x;(斜向反方向)

遇到上述問題之一的時候,說明我們已經(jīng)遇到了障礙,不能繼續(xù)向前了。我們需要退回來,嘗試其他路徑。

我們將棋盤看作是一個8*8的數(shù)組,這樣可以使用一種蠻干的思路去解決這個問題,這樣我們就是在8*8=64個格子中取出8個的組合,C(64,80) = 4426165368,顯然這個數(shù)非常大,在蠻干的基礎(chǔ)上我們可以增加回溯,從第0列開始,我們逐列進(jìn)行,從第0行到第7行找到一個不受任何已經(jīng)現(xiàn)有皇后攻擊的位置,而第五列,我們會發(fā)現(xiàn)找不到皇后的安全位置了,前面四列的擺放如下:

/uploads/cj/201910/201606151029092.png

第五列的時候,擺放任何行都會上圖所示已經(jīng)存在的皇后的攻擊,這時候我們認(rèn)為我們撞了南墻了,是回頭的時候了,我們后退一列,將原來擺放在第四列的皇后(3,4)拿走,從(3,4)這個位置開始,我們再第四列中尋找下一個安全位置為(7,4),再繼續(xù)到第五列,發(fā)現(xiàn)第五列仍然沒有安全位置,回溯到第四列,此時第四列也是一個死胡同了,我們再回溯到第三列,這樣前進(jìn)幾步,回退一步,最終直到在第8列上找到一個安全位置(成功)或者第一列已經(jīng)是死胡同,但是第8列仍然沒有找到安全位置為止

總結(jié)一下,用回溯的方法解決8皇后問題的步驟為:

1)從第一列開始,為皇后找到安全位置,然后跳到下一列

2)如果在第n列出現(xiàn)死胡同,如果該列為第一列,棋局失敗,否則后退到上一列,在進(jìn)行回溯

3)如果在第8列上找到了安全位置,則棋局成功。

8個皇后都找到了安全位置代表棋局的成功,用一個長度為8的整數(shù)數(shù)組queenList代表成功擺放的8個皇后,數(shù)組索引代表棋盤的col向量,而數(shù)組的值為棋盤的row向

量,所以(row,col)的皇后可以表示為(queenList[col],col),如上圖中的幾個皇后可表示為:

queenList[0] = 0;  queenList[1] = 3;   queenList[2] = 1;  queenList[3] = 4;   queenList = 2;

我們看一下如何設(shè)計程序:

首先判斷(row,col)是否是安全位置的算法:

bool IsSafe(int col,int row,int[] queenList){ //只檢查前面的列 for (int tempCol = 0; tempCol < col; tempCol++) {  int tempRow = queenList[tempCol];  if (tempRow == row)  {   //同一行   return false;  }  if (tempCol == col)  {   //同一列   return false;  }  if (tempRow - tempCol == row - col || tempRow + tempCol == row + col)  {   return false;  } } return true;}
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 福泉市| 陈巴尔虎旗| 洛扎县| 安庆市| 铜山县| 府谷县| 晋城| 鲁山县| 松溪县| 崇礼县| 平邑县| 房山区| 永顺县| 平阴县| 五台县| 富源县| 高邑县| 临夏市| 昔阳县| 红安县| 铜川市| 阳曲县| 南溪县| 宁南县| 万盛区| 林周县| 体育| 松溪县| 蓬安县| 龙南县| 崇阳县| 宁明县| 六安市| 乐至县| 平阳县| 苏州市| 察哈| 怀宁县| 昌邑市| 汤阴县| 峨眉山市|