N 皇后问题在此就不多介绍了,相信CS的同学都应经清楚了,不清楚也可自行Google(听说国内用不了Google了?令人发指!)。在此以一道例题为引。
hdu-2553 1 #include <iostream>
2 #include <math.h> 3 using namespace std; 4 5 #define MAX 12 6 7 int n; 8 int solution_num; 9 int row[MAX]={0}; 10 int result[MAX];
11 int is_valid(int posted_num){ 12 for(int i = 0; i < posted_num; i++){ 13 if(row[i] == row[posted_num] || abs((row[posted_num] - row[i])) == abs(posted_num - i) ) 14 return 0; 15 } 16 return 1; 17 } 18 19 void test(int posted_num){ 20 //under which condition RETURN 21 if(posted_num == n){ 22 solution_num++; 23 return; 24 } 25 for(int i = 1;i <= n; i++){ 26 row[posted_num] = i; 27 if(is_valid(posted_num)){ 28 test(posted_num+1); 29 } 30 } 31 } 32 33 int main(int argc, const char * argv[]) { 34 35 for(n = 1;n <= MAX-2;n++){ 36 solution_num = 0 ; 37 test(0); 38 result[n] = solution_num; 39 } 40 while(cin>>n,n){ 41 cout<<result[n]<<endl; 42 } 43 return 0; 44 }
其实上述代码就是暴力解决,先在第一列某一位置放置一个皇后,标记行号row[i](row[i]不能再放皇后了,否则会冲突),再在第二列寻找可能合法的位置,blablabla,直到N个皇后全部放好后,递归结束。可能会有人在判断可行性的时候会有疑惑。横竖判断肯定没问题,在判断斜线时,我们利用斜率不等于正负1来判断,而这两点在棋盘中的坐标,恰好可以利用(posted_num,row[posted_num])和(i,row[i])来表示,这个小技巧优化了存储空间和代码复杂度。
为不超时,采用了打表的方法进行提交并通过。
有递归不超时的算法??下次为大家带来超强位运算解NQUEEN问题的详解!