题目描述
给出一个棋盘,任意两个棋子不能放在同一行或者同一列,问共有多少种方法。
输入格式
第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域(可放置), . 表示空白区域(不可放置)
(数据保证不出现多余的空白行或者空白列)。
输出格式
对于每一组数据,给出一行输出,输出摆放的方案数目C。
样例输入
2 1
#.
.#
4 4
...#
..#.
.#..
#...
样例输出
2
1
提示
#的位置可放置棋子\
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <set>
using namespace std;
typedef long long ll;
const int maxx = 1000050;
int n, m, k, t, now, p, ans;
const double pi = acos(-1.0);
ll a[1000050];
char e[220][220];
int w[220];//表示该层能否发放置//false 代表未被放置
//每层都有两种方案(在棋子数没被放完之前
void dfs(int x, int y)//x代表运行到的层数//y代表
{
if (y == 0)//合法判定 //也就是说符合要求,
{
ans++;//方案++
return;
}
if (x == m + 1)//越界回溯
{
return;
}
for (int i = 1; i <= m; i++)//该层要放置
{
if (e[x][i] == '#' && w[i] == false)
{
w[i] = 1;//放置
dfs(x + 1, y - 1);
w[i] = 0;//递归结束,为了下一次的情况,将放置的情况取消
}
}
//不放置
dfs(x + 1, y);//层数+1 , 棋子数不变
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while (cin >> m >> n)
{
ans = 0;
memset(e, 0, sizeof(e));
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> e[i][j];
}
}
dfs(1, n);//从第一行开始遍历
cout << ans << endl;//输出遍历完的答案
}
return 0;
}