1. 程式人生 > >POJ 1321

POJ 1321

cin ret 輸入 continue sin TP cst include bmi

棋盤問題
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

對於每一組數據,給出一行輸出,輸出擺放的方案數目C (數據保證C<2^31)。

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 namespace
std; 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