題目:
在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。
輸入:
輸入含有多組測試數據。
每組數據的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n
當為-1 -1時表示輸入結束。
隨后的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多余的空白行或者空白列)。
輸出:
對於每一組數據,給出一行輸出,輸出擺放的方案數目C (數據保證C<2^31)。
樣例:

分析:及AC代碼如下
#include<iostream>
#include<sstream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<numeric>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<cctype>
#define PI acos(-1.0)
const int INF = 0x3f3f3f;
const int NINF = -INF - 1;
typedef long long ll;
using namespace std;
int n, k, num;//記錄答案
int used[10];//記錄此列已經被使用
int judge[10][10];//記錄此格是否為棋盤區域
char c[10][10];//記錄棋盤
void func(int x, int y, int t)//t記錄當前已有幾個棋子
{
if (t == k)
{
//cout << x << ' ' << y << ' ' << t << endl;
num++;
return;
}
for (int i = x + 1; i < n; ++i)//每次從下一行開始搜索
{
for (int j = 0; j < n; ++j)
{
if (judge[i][j] && !used[j])
{
//cout << i << ' ' << j << ' ' << t << endl;
used[j] = 1;
func(i, j, t + 1);
used[j] = 0;//完成后復位
}
}
}
}
int main()
{
while (cin >> n >> k)
{
if (n == -1 && k == -1) break;
num = 0;//初始化
memset(used, 0, sizeof(used));
memset(judge, 0, sizeof(judge));
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cin >> c[i][j];
if (c[i][j] == '#') judge[i][j] = 1;//記錄該格為棋盤區域
}
}
func(-1, 0, 0);//x=-1,第一次即從0開始(i=x+1)
cout << num << endl;
}
return 0;
}
