- 題目描述:
-
N皇后問題,即在N*N的方格棋盤內放置了N個皇后,使得它們不相互攻擊(即任意2個皇后不允許處在同一排,同一列,也不允許處在同一斜線上。因爲皇后可以直走,橫走和斜走如下圖)。
你的任務是,對於給定的N,求出有多少種合法的放置方法。輸出N皇后問題所有不同的擺放情況個數。
- 輸入:
-
輸入包含多組測試數據。
每組測試數據輸入一個整數n(3<n<=13),表示有n*n的棋盤,總共擺放n個皇后。
- 輸出:
-
對於每組測試數據,輸出總共不同的擺放情況個數,結果單獨一行。
- 樣例輸入:
-
4
- 樣例輸出:
-
2
-
-
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
方法一:用普通的遞歸,每行去判斷當前位置是否符合條件,每個位置需要判斷3根線上的點是否已經有皇后了,複雜度相當高,會超時。
-
方法二:用位運算,每根線用一個bit表示有無皇后,每個位置都可以換算成對應線上獨一無二的點,相同斜線上的點對應線上同一個位置,大大減輕了運算的複雜度,代碼如下:
-
-
#include<stdio.h> using namespace std; int n,sum; bool dps(int a,int b,int c,int d)//a是列位置,b是右斜線的位置,c是左斜線的位置,d是行位置 { if(d>=n) { sum++; return true; } int j; for(j=0;j<n;j++) if((a&(1<<j))==0 && (b&(1<<(j+d)))==0 && (c&(1<<(j-d+n)))==0)//位置沒有被佔,則下一行 dps(a^(1<<j),b^(1<<(j+d)),c^(1<<(j-d+n)),d+1); return true; } int main() { while(scanf("%d",&n)!=EOF) { sum=0; dps(0,0,0,0); printf("%d\n",sum); } return 0; } /************************************************************** Problem: 1254 User: 午夜小白龍 Language: C++ Result: Accepted Time:530 ms Memory:1020 kb ****************************************************************/