这是我应聘如今这家公司的面试题,当时没作好,如今网上这个问题的代码已经不少了,问题也很透彻,排除由于棋盘的对称性带来的对称解,总共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种能够所有打印出来:
结果中数字表明列数。