一道演算法題-八皇后問題(C++實現)

來源:互聯網
上載者:User

標籤:gpo   pac   深度   bsp   iostream   use   htm   解法   遍曆   

八皇后問題

一、題意解析

  國際象棋中的皇后,可以橫向、縱向、斜向移動。如何在一個8X8的棋盤上放置8個皇后,使得任意兩個皇后都不在同一條橫線、豎線、斜線方向上?八皇后問題是一個古老的問題,於1848年由一位國際象棋棋手提出:在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,如何求解?以高斯為代表的許多數學家先後研究過這個問題。後來,當電腦問世,通過電腦程式的運算可以輕鬆解出這個問題。

二、如何解決八皇后問題?

  所謂遞迴回溯,本質上是一種枚舉法。這種方法從棋盤的第一行開始嘗試擺放第一個皇后,擺放成功後,遞迴一層,再遵循規則在棋盤第二行來擺放第二個皇后。如果當前位置無法擺放,則向右移動一格再次嘗試,如果擺放成功,則繼續遞迴一層,擺放第三個皇后......

  如果某一層看遍了所有格子,都無法成功擺放,則回溯到上一個皇后,讓上一個皇后右移一格,再進行遞迴。如果八個皇后都擺放完畢且符合規則,那麼就得到了其中一種正確的解法。說起來有些抽象,我們來看一看遞迴回溯的詳細過程。

  1.第一層遞迴,嘗試在第一行擺放第一個皇后

  2.第二層遞迴,嘗試在第二行擺放第二個皇后(前兩格被第一個皇后封鎖,只能落在第三格):

  3.第三層遞迴,嘗試在第三行擺放第三個皇后(前四格被第一第二個皇后封鎖,只能落在第五格):

  4.第四層遞迴,嘗試在第四行擺放第四個皇后(第一格被第二個皇后封鎖,只能落在第二格):

  5.第五層遞迴,嘗試在第五行擺放第五個皇后(前三格被前面的皇后封鎖,只能落在第四格):

  6.由於所有格子都“綠了”,第六行已經沒辦法擺放皇后,於是進行回溯,重新擺放第五個皇后第八格。:

  7.第六行仍然沒有辦法擺放皇后,第五行也已經嘗試遍了,於是回溯到第四行,重新擺放第四個皇后第七格。:

  8.繼續擺放第五個皇后,以此類推......

三、八皇后問題的代碼實現

  解決八皇后問題,可以分為兩個層面:

1.找出第一種正確擺放方式,也就是深度優先遍曆。

2.找出全部的正確擺放方式,也就是廣度優先遍曆。

 我們本篇只介紹如何找出第一種正確擺放方式。具體代碼如下:

  1 //"八皇后問題回溯實現"  2 #include <iostream>  3 using namespace std;  4 const int ArSize = 8;//這個數等於幾,就是幾皇后。  5 int num = 0;  6 void solve(bool arr[ArSize][ArSize], int row);  7 bool check(bool arr[ArSize][ArSize], int row, int column);  8 void outPut(bool arr[ArSize][ArSize]);  9  10 int main() 11 { 12     bool chessboard[ArSize][ArSize]; 13     // 數組初始化 14     for (auto &i : chessboard) 15     { 16         for (auto &j : i) 17         { 18             j = false; 19         } 20     } 21     solve(chessboard, 0); 22     cout << "八皇后問題共有" << num << "種解!" << endl; 23     system("pause"); 24     return 0; 25 } 26 // 回溯法 27 void solve(bool arr[ArSize][ArSize], int row) 28 { 29     for (int column = 0; column < ArSize; ++column) 30     { 31         arr[row][column] = true; 32         if (check(arr, row, column)) 33         { 34             if (row + 1 == ArSize) 35             { 36                 outPut(arr); 37             } 38             else 39             { 40                 solve(arr, row + 1); 41             } 42         } 43         arr[row][column] = false; 44     } 45 } 46 // 判斷皇后的落點是否合規 47 bool check(bool arr[ArSize][ArSize], int row, int column) 48 { 49     if (row == 0) 50     { 51         return true; 52     } 53     int i, j; 54     // 判斷縱向是否有衝突 55     for (i = 0; i < row; ++i) 56     { 57         if (arr[i][column]) 58         { 59             return false; 60         } 61     } 62     i = row - 1; 63     j = column - 1; 64     // 判斷正斜對角線是否有衝突 65     while (i >= 0 && j >= 0) 66     { 67         if (arr[i][j]) 68         { 69             return false; 70         } 71         --i; 72         --j; 73     } 74     i = row - 1; 75     j = column + 1; 76     // 判斷負斜對角線是否有衝突 77     while (i >= 0 && j <= ArSize - 1) 78     { 79         if (arr[i][j]) 80         { 81             return false; 82         } 83         --i; 84         ++j; 85     } 86     return true; 87 } 88 // 列印每種正確的解法 89 void outPut(bool arr[ArSize][ArSize]) 90 { 91     ++num; 92     cout << "**********************" << num << "*********************" << endl; 93     for (int i = 0; i < ArSize; ++i) 94     { 95         for (int j = 0; j < ArSize; ++j) 96         { 97             cout << arr[i][j] << " "; 98         } 99         cout << endl;100     }101     cout << "*********************************************" << endl;102 }

  輸出結果的部分如下:

 

 

參考資料:

http://www.cnblogs.com/yonggandefeng/p/6275861.html

一道演算法題-八皇后問題(C++實現)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.