题目链接:http://poj.org/problem?id=1321
分析
这道题跟n皇后问题的思路差不多,只不过棋子的个数可能小于n,所以有些行可以不放棋子
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
int n,k;
char a[10][10],b[10];
ll ans;
bool isValid(int x,int y)
{
if(a[x][y] == '.') return false;
for(int i = 0; i < x; i++)
if(b[i] == y) return false;
return true;
}
void dfs(int m,int cnt)//m表示当前行,cnt表示当前已经放好的棋子数
{
if(cnt == k) {
ans++;
return;
}
if(m == n) return;
for(int i = 0; i < n; i++)
if(isValid(m,i)) {
b[m] = i;
dfs(m + 1,cnt + 1);
}
b[m] = -1;
//当前行不放棋子
if(n - m + cnt >= k) dfs(m + 1,cnt);//剪枝
}
int main()
{
while(scanf("%d%d",&n,&k)) {
if(n == -1 && k == -1) break;
memset(b,-1,sizeof(b));
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf(" %c",&a[i][j]);
ans = 0;
dfs(0,0);
printf("%lld\n",ans);
}
return 0;
}