這是我應聘如今這家公司的面試題,當時沒作好,如今網上這個問題的代碼已經不少了,問題也很透徹,排除由於棋盤的對稱性帶來的對稱解,總共92種解法。ios
八後問題最多見的解法就是遍歷法,一個八叉的遍歷問題具體操做以下:面試
因爲這個問題確定是每行有一個後,把起始設爲第一行算法
1.從第一列開始,放下一個後。oop
2.轉移到第二行,從第一列,防下一個後,檢驗是否與前面衝突,若衝突,轉到下一列;若不衝突,轉移到下一行。以此類推。this
這個問題是一個典型的嵌套循環, 從第一行開始,執行8次循環,從第1列到第7列。——第一層循環spa
在第一層循環中,一旦成功放置旗子,則進入第二層循環,執行8次,從第1列到第7列,放置棋子前,要檢驗是否與已放置旗子衝突,若衝突,到下一列。——第二層循環code
在第二層循環中,一旦成功放置旗子,則進入第三層循環,執行8次,從第1列到第7列,放置棋子前,要檢驗是否與已放置旗子衝突,若衝突,到下一列。——第三層循環blog
在第三層循環中,一旦成功放置旗子,則進入第四層循環,執行8次,從第1列到第7列,放置棋子前,要檢驗是否與已放置旗子衝突,若衝突,到下一列。——第四層循環io
.(從第五行開始可能會出現全行都衝突的狀況,這時候會跳出循環,進入到上一層循環的下一列,而後再回到這層循環)class
.
.
當到第七行後,如有不衝突的位置,則直接打印。
把衝突檢測包裝在方法裏才能很好的兼容循環,那麼如何才能最快的檢驗當前點(current_x,current_y),與現有的各個點(exist_x,exist_y)衝突呢,
首先一點就是,當我在循環中判斷當前點是否衝突時,我只需判斷當前行以前的各行便可,不會出現同行的狀況。
因此判斷的第一點就是是否同列:if(current_y==exist+y)
判斷的第二點就是斜線方向了,斜線兩個方向(current_x-current_y==exist_x-exisy_y) 和(current_x+current_y==exist_x+exisy_y)
這三個條件都不知足,纔算不衝突,繼續進入循環。
代碼以下:
1 // 8-Queen_project.cpp : 定義控制檯應用程序的入口點。 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 using namespace std; 7 8 static int result_array[8] = { 0 }, total_count = 0; 9 void print() //打印 10 { 11 for (int i = 0; i < 8; i++) 12 { 13 for (int j = 0; j < result_array[i]; j++) 14 cout << " "; 15 cout << result_array[i] << endl; 16 } 17 cout << "--------\n"; 18 } 19 int confliction(int c_row, int c_column) 20 { 21 int this_row; 22 int this_column; 23 for (this_row = 0; this_row < c_row; this_row++) //只檢驗上面的行 24 { 25 this_column = result_array[this_row]; 26 if (c_column == this_column) 27 return 0; 28 if ((this_row + this_column) == (c_row + c_column)) 29 return 0; 30 if ((this_row - this_column) == (c_row - c_column)) 31 return 0; 32 } 33 return 1; 34 } 35 void loop(int row) // 參數就是行數 36 { 37 int column; 38 for (column = 0; column < 8; column++)//下面全部級的循環都結束,進入下一列 39 { 40 if (confliction(row, column)) 41 { 42 result_array[row] = column; 43 if (row == 7) //到最後一行打印 44 { 45 total_count++, print(); 46 result_array[row] = 0; 47 return; 48 } 49 loop(row + 1); //進入下一行循環 50 result_array[row] = 0; 51 } 52 } 53 } 54 int main(int argc, char*argv[]) 55 { 56 loop(0); 57 cout << "total=" << total_count << endl; 58 return 0; 59 }
結果以下,92種能夠所有打印出來:
結果中數字表明列數。