POJ 1321
阿新 • • 發佈:2018-05-18
cin ret 輸入 continue sin TP cst include bmi 棋盤問題
每組數據的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
隨後的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多余的空白行或者空白列)。
對於每一組數據,給出一行輸出,輸出擺放的方案數目C (數據保證C<2^31)。
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 61105 | Accepted: 29271 |
Description
在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。Input
輸入含有多組測試數據。每組數據的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
隨後的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多余的空白行或者空白列)。
Output
Sample Input
2 1 #. .# 4 4 ...# ..#. .#.. #... -1 -1
Sample Output
2 1
解析:要考慮兩種情況 放還是不放 如果放 遍歷列 找到每行的‘#’ vis標記列 如果不放直接到下一行即可 dfs兩個參數 一個行 一個時是已經放的棋子數
#include <iostream> #include <cstring> #define mem(a,b) memset(a,b,sizeof(a)) using namespacestd; const int maxn = 1010; int cnt = 0,vis[maxn],n,k; char str[maxn][maxn]; void dfs(int r,int idx) { if(r > n-1) { if(idx == k) cnt++; return; } dfs(r+1,idx); //不放 for(int i=0;i<n;i++) //如果放 則遍歷列 { if(str[r][i] == ‘.‘ || vis[i])continue; vis[i] = 1; dfs(r+1,idx+1); vis[i] = 0; } } int main() { while(cin>>n>>k && (n != -1 || k != -1)) { cnt = 0; mem(vis,0); mem(str,0); for(int i=0;i<n;i++) cin>>str[i]; dfs(0,0); cout<<cnt<<endl; } return 0; }
POJ 1321