Description
在N*N的方格棋盤放置了N個皇後,使得它們不相互攻擊(即任意2個皇後不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。Input
共有若干行,每行一個正整數N≤10,表示棋盤和皇後的數量;如果N=0,表示結束。Output
共有若干行,每行一個正整數,表示對應輸入行的皇後的不同放置數量。Sample Input
1 8 5 0Sample Output
1 92 10 題解:此題采用的是遞歸枚舉法(回溯法)。本題采用逐行放置。要預先把合法的放置方法數保存起來 設皇後的編號依次為1,2,……,n,則可以認為第i個皇後必須擺放在第i行,然後枚舉第一個皇後的位置進行回溯,若某一次發現某個皇後無法找到擺放位置則直接返回,如果所有皇後都可以找到擺放位置,則說明存在一種擺法滿足要求,統計有多少種擺法即可。 思路:每行最多只能有一個皇後,所以用a[ ]表示行向量,搜索從第一個行向量開始 1 #include<iostream>
2 #include<cmath>
3 using namespace std;
4 const int maxn=11;
5 int b[maxn],a[maxn],sum,n;
6
7 void dfs(int cur)
8 {
9 if(cur == n+1)//遞歸邊界,就有一種擺法
10 sum++;
11 else
12 for(int j = 1; j <=n; j++)
13 {
14 int ok=1;
15 a[cur] = j;//嘗試把第cur行的皇後放在第j列
16 for(int i = 1; i<cur; i++) //檢查是否和前面的皇後沖突
17 if(a[i] == a[cur] || abs(i - cur) == abs(a[i] - a[cur]))
18 {
19 ok=0;
20 break;
21 }
22 if(ok)
23 dfs(cur+1);//如果合法,繼續遞歸
24 }
25 }
26
27 int main()
28 {
29 for(int i = 1; i <=maxn; i++)
30 {
31 sum = 0;
32 n= i;
33 dfs(1);
34 b[i] = sum;
35 }
36 while(cin>>n && n)
37 cout<<b[n]<<endl;
38 return 0;
39 }
一不小心找到了一個超簡單,投機取巧的方法。。。。因為n<=10。但是不能ac。
1 #include <cstdio>
2 main()
3 {
4 int n,a[13]={0,1,0,0,2,10,4,40,92,352,724,2680,14200};
5 while(scanf("%d",&n))
6 printf("%d\n",a[n]);
7 }