棋盤問題
time limit:1000ms
memory limit:10000k
total submissions:60012
accepted:28756
description
在乙個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案c。
input
輸入含有多組測試資料。
每組資料的第一行是兩個正整數,n k,用乙個空格隔開,表示了將在乙個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
隨後的n行描述了棋盤的形狀:每行有n個字元,其中 # 表示棋盤區域, . 表示空白區域(資料保證不出現多餘的空白行或者空白列)。
output
對於每一組資料,給出一行輸出,輸出擺放的方案數目c (資料保證c<2^31)。
sample input
2 1sample output#..#
4 4...#
..#.
.#..
#...
-1 -1
21
本人初學深搜,遇到此題,才發現深搜還是很難的。(ps:以前我遇到的深搜題都是乙個模板)。這道題我看了諸位大神的部落格後,才真正理解此題。
其實深搜是一種思想,不應該認為記住模板就行了(其他演算法也一樣)。這道題的關鍵在於如何去搜,根據題目要求(要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列
)。我們可以這樣去搜尋,我們每次一行一行的遍歷棋盤。如果在這一行的乙個棋盤位置放上棋子之後。就標記這一列,遍歷下面幾行的時候就跳過這一列。例如:
...#遍歷第一行,找到第3列#之後,就把第3列標記。..#.
.#..
#...
遍歷第二行(由於第三列被標記只遍歷第0,1, 2列),找到第2列#之後,把第二列標記。
遍歷第三行(由於第三列和第二列被標記了,只遍歷第0,1列),找到第1列#之後,把第一列標記。
.......
這道題還有乙個關鍵點,就是不一定下乙個棋子的位置就在下一行,可能是下兩行、下三行......
這個怎麼解決? 其實在每一行遍歷完之後,直接遍歷下一行(具體內容看了**就懂了)
#include using namespace std;
char mp[12][12]; //裝棋盤
int n, k; //棋盤的大小以及棋子的個數
int cnt, num; //記錄次數以及棋子的個數
int vis[12]; //標記棋子所在的那一列
void dfs(int i)
if (i >= n)
for (int j = 0; j < n; ++j)
}dfs(i + 1); //本題的核心, 如果進行到這一步,意味著這一行乙個棋子都不放,請認真理解。
}int main()
}for (int i = 0; i < 12; ++i) //初始化
vis[12] = 0;
cnt = 0;
num = 0;
dfs(0); //進行深搜
cout << cnt << endl; //輸出次數
}}
POJ 1321 棋盤問題 深搜)
漢語題意,題目類似八皇后問題,深搜即可。貌似可以用狀態壓縮過,有空再研究研究。172k 63ms include include include define n 9 using namespace std bool graph n n bool flag n n bool column n int...
poj 1321 棋盤問題(深搜)
棋盤問題 time limit 1000ms memory limit 10000k total submissions 45433 accepted 21996 description 在乙個給定形狀的棋盤 形狀可能是不規則的 上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同...
POJ 1321 棋盤問題(深搜)
棋盤問題 time limit 1000ms memory limit 10000k total submissions 55077 accepted 26514 description 在乙個給定形狀的棋盤 形狀可能是不規則的 上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同...