题目大意是给你一个N*N的不规则棋盘。'#’表示棋盘区域。然后呢。给你K个棋子。要求每行每列最多只能放1个棋子。问你最多有多少种放法。
思路就是从第一行第一个位置开始深搜。如果符合条件就放上棋子。然后搜索下一行并且棋子数加1。因为行是按顺序搜索的。所以只要判断该列是不是放过棋子了就行了。然后呢。每次搜索前判断棋子是不是已经用完。如果用完了记录方案数加1。然后直接返回。直到所有搜索完成就得到所有方案数。还要注意修改标记后递归回来要及时复原。
附代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int n, k;
bool map[15][15];
bool vis[15];
int ans;
void Dfs(int col, int now)
{
if (now == k)
{
ans++;
return;
}
for (int i=col; i<n; ++i)
{
for (int j=0; j<n; ++j)
{
if (map[i][j] && !vis[j])
{
vis[j] = 1;
Dfs(i+1, now+1);
vis[j] = 0;
}
}
}
}
int main()
{
while(cin >> n >> k)
{
if (n == -1 && k == -1)
break;
ans = 0;
memset(map, false, sizeof(map));
memset(vis, false, sizeof(vis));
for (int i=0; i<n; ++i)
{
for (int j=0; j<n; ++j)
{
char temp;
cin >> temp;
if (temp == '#') map[i][j] = true;
}
}
Dfs(0, 0);
cout << ans << endl;
}
return 0;
}