九度oj 题目1254:N皇后问题
题目描述:
N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。
-
你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。
- 输入:
-
输入包含多组测试数据。
每组测试数据输入一个整数n(3<n<=13),表示有n*n的棋盘,总共摆放n个皇后。
- 输出:
-
对于每组测试数据,输出总共不同的摆放情况个数,结果单独一行。
- 样例输入:
-
4
- 样例输出:
-
2
开始的代码如下1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 8 int cnt[15]; 9 int ans[15]; 10 11 int pan(int row, int col) { 12 int panA = col - row; 13 int panB = col + row; 14 for(int i = 0; i < row; i++) { 15 if(ans[i] - i == panA || ans[i] + i == panB || ans[i] == col) { 16 return false; 17 } 18 } 19 return true; 20 } 21 void dfs(int row, int n) { 22 if(row == n) { 23 cnt[n]++; 24 return; 25 } 26 for(int i = 0; i < n; i++) { 27 if(pan(row, i)) { 28 ans[row] = i; 29 dfs(row+1, n); 30 } 31 } 32 } 33 34 int main(int argc, char const *argv[]) 35 { 36 int n; 37 while(scanf("%d",&n) != EOF){ 38 memset(cnt, 0, sizeof(cnt)); 39 dfs(0, n); 40 printf("%d\n",cnt[n]); 41 } 42 43 return 0; 44 }
用一个一维数组存储放置的状态,用回溯法求解,但这样做还是太慢,提交时采用暴力的办法
1 #include <cstdio> 2 3 int cnt[15]= {0,0,0,0,2,10,4,40,92,352,724,2680,14200,73712}; 4 5 int main(int argc, char const *argv[]) 6 { 7 int n; 8 while(scanf("%d",&n) != EOF){ 9 printf("%d\n",cnt[n]); 10 } 11 return 0; 12 } 13
参考别人博客,用位运算来求解是最快的办法