在一个n*n 的国际象棋棋盘上放置n 个皇后,使得它们中任意2 个之间都不互相“攻击”,即任意2 个皇后不可在同行、同列、同斜线上。求N 皇后问题的所有放法。
输入n:
输出:每行输出一种方案,每种方案顺序输出皇后所在的列号,各个数之间用空格隔开。
样例输入:
4
样例输出:
2 4 1 3
3 1 4 2
一道dfs。只要判断放的这个棋子在行,列,对角线上的合法性就行。
不过一个优化就是我们逐行放,这样就能保证每一行上的棋子一定只有一个。
再开三个数字记录每一列,从左上到右下,从右上到左下斜线上的放置情况。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 using namespace std; 7 typedef long long ll; 8 int a[15], n, cnt = 0; 9 int lx[30], rx[30], path[15]; 10 void print() 11 { 12 for(int i = 1; i <= n; ++i) printf("%d ", path[i]); 13 printf(" "); 14 } 15 void dfs(int x) 16 { 17 if(x == n + 1) {print(); return;} 18 for(int i = 1; i <= n; ++i) 19 { 20 if(!a[i] && !lx[x - i + n] && !rx[x + i]) 21 { 22 a[i] = lx[x - i + n] = rx[x + i] = 1; 23 path[x] = i; 24 dfs(x + 1); 25 a[i] = lx[x - i + n] = rx[x + i] = 0; 26 } 27 } 28 } 29 int main() 30 { 31 scanf("%d", &n); 32 dfs(1); 33 return 0; 34 }
模拟的时候我竟然奇迹般的没看到这道题……
贴一个用位运算优化的n皇后,不过只能输出有多少个解。(然而我也有些忘了这代码是怎么回事了……)
#include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<iostream> using namespace std; typedef long long ll; using namespace std; int a[15], n, cnt = 0; int lx[30], rx[30], path[15]; void dfs2(int row, int ld, int rd) { if(row == (1 << n) - 1) {cnt++; return;} int pos = (~(row | ld | rd)) & ((1 << n) - 1); while(pos) { int nowbit = pos & -pos; dfs2(row | nowbit, (ld | nowbit) << 1, (rd | nowbit) >> 1); pos ^= nowbit; } } int main() { scanf("%d", &n); dfs2(0, 0, 0); printf("%d ", cnt); }