檢查乙個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行、每列有且只有乙個,每條對角線(包括兩條主對角線的所有平行線)上至多有乙個棋子。
上面的布局可以用序列2 4 6 1 3 5來描述,第i個數字表示在第i行的相應位置有乙個棋子,如下:
行號 1 2 3 4 5 6
列號 2 4 6 1 3 5
這只是跳棋放置的乙個解。請編乙個程式找出所有跳棋放置的解。並把它們以上面的序列方法輸出。解按字典順序排列。請輸出前3個解。最後一行是解的總個數。
//以下的話來自usaco官方,不代表洛谷觀點
特別注意: 對於更大的n(棋盤大小n x n)你的程式應當改進得更有效。不要事先計算出所有解然後只輸出(或是找到乙個關於它的公式),這是作弊。如果你堅持作弊,那麼你登陸usaco training的帳號刪除並且不能參加usaco的任何競賽。我警告過你了!
輸入格式:
乙個數字n (6 <= n <= 13) 表示棋盤是n x n大小的。
輸出格式:
前三行為前三個解,每個解的兩個數字之間用乙個空格隔開。第四行只有乙個數字,表示解的總數。
輸入樣例#1:
6
輸出樣例#1:
2 4 6 1 3 53 6 2 5 1 4
4 1 5 2 6 3
4
題目翻譯來自nocow。
usaco training section 1.5
分析:顯然問題的關鍵在於如何判定某個皇后所在的行,列,斜線上是否有別的皇后;可以從矩陣的特點上找到規律,如果在同一行,則行號相同;如果在同一列上,則列號相同;如果同在/ 斜線上的行列值之和相同;如果同在\ 斜線上的行列值之差相同
考慮每一行只能有乙個皇后(根據題意同行不能有兩個皇后)我們可以建立乙個ans陣列來儲存每個皇后的位置ans[i]下表i代表行數內容代表列數
另外根據我們找到的規律可以建立a,b,c,d四個陣列分別用來標記對角線的四個方向,我們可以使用回溯演算法放置皇后時對該皇后的行列對角線進行占用標記。一種方案執行完後,再釋放標記!
此題採用的是一維陣列操作,使問題變得更加容易理解!
下面給出ac**:
1 #include 2using
namespace
std;
3const
int maxn=1000010
;4 typedef long
long
ll;5
int a[maxn],b[maxn],c[maxn],d[maxn],ans[maxn],n,tim=0
;6 inline void
print()
714 ++tim;
15return;16
}17 inline int dfs(int k)//
深度優先搜尋,k指代接下去放的是第k個棋子
1838
continue;39
}40}41
}42intmain()
43
洛谷P1219 八皇后 dfs
檢查乙個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行 每列有且只有乙個,每條對角線 包括兩條主對角線的所有平行線 上至多有乙個棋子。上面的布局可以用序列2 4 6 1 3 5來描述,第i個數字表示在第i行的相應位置有乙個棋子,如下 行號 1 2 3 4 5 6 列號 2 4 6 1...
八皇后 dfs 洛谷P1219
p1219 usaco1.5 八皇后 checker challenge 題意 n n的棋盤,放置n個皇后,使其不會互相攻擊。同行 同列 同對角線會相互攻擊。按字典序輸出前三個,第四行輸出一共有多少種放法。做法 陣列a i 存放第i行的皇后放在哪一列,遞迴列舉全排列。列舉過程中判合法 可行性剪枝 判...
洛谷 P1219 八皇后 DFS
時間限制1.00s 記憶體限制125.00mb 檢查乙個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行 每列有且只有乙個,每條對角線 包括兩條主對角線的所有平行線 上至多有乙個棋子。上面的布局可以用序列2 4 6 1 3 5來描述,第i個數字表示在第i行的相應位置有乙個棋子,如下 行...