思路:递归 + 回溯
按行检索每一列的位置是否能放皇后就用到递归,这一行放完再进入下一行,搜索每一行时都有n次循环,每次占领一个就宣布它的同列,左下划线,右下划线已被占领
三个数组:a[100], b[100], c[100];
同列:若占领,a[j]标记为1
左下划线:若占领,b[cnt+j]标记为1
右下划线:若占领,c[cnt-j+n]标记为1, 为什么要加n呢,因为避免出现负数的情况
用三个数组作用就是:用一个数表示整列,整斜线都被占领
递归结束条件:当 cnt > n , 即放完第n个皇后就开始回溯,判断第n行是否还有可以放的地方,没有的话再回溯以此类推。
代码:
1 #include<iostream> 2 3 using namespace std; 4 5 int n, sum; 6 bool a[100], b[100], c[100]; //a表示列 b表示右下划线 c表示左下划线 7 int res[100]; 8 void print() 9 { 10 for(int i = 1; i <= n; i++) 11 { 12 cout << res[i] << " "; 13 } 14 cout << endl; 15 } 16 17 void dfs(int cnt) 18 { 19 if(cnt > n) 20 { 21 sum++; 22 return; 23 } 24 25 for(int i = 1; i <= n; i++) 26 { 27 if( (!a[i]) && (!b[cnt+i]) && (!c[cnt-i+n])) //如果没有被占领 28 { 29 res[cnt] = i; 30 a[i] = 1; 31 b[cnt+i] = 1; 32 c[cnt-i+n] = 1; 33 34 dfs(cnt+1); 35 //回溯 36 a[i] = 0; 37 b[cnt+i] = 0; 38 c[cnt-i+n] = 0; 39 } 40 } 41 42 } 43 44 int main() 45 { 46 cin >> n; 47 dfs(1); 48 cout << sum; 49 system("pause"); 50 return 0; 51 }