直接暴搜就ok,按行dfs,那么行就不会冲突,然后再对列进行标记,判断同一列是否冲突。
做完这道题之后有几个感受:首先总体思路很浅显直白,但在细节实现上,有好多盲点没注意到,还是看discuss上的数据才找到bug,郁闷~~~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
char Map[10][10];
int flag[10];
int n,k,ans;
void dfs(int x,int num){
if(num==0){
ans++;
return;
}
//cout<<num<<endl;
int flag1=0;
for(int i=0;i<n;i++){
if(Map[x][i]=='#'&&flag[i]!=1){
if(!flag1){ //当前行如果有可行点,num只能自减1次,之后的可行点就不需再自减了
num--;
flag1=1;
}
flag[i]=1;
for(int j=x+1;j<=n-num+1;j++){ //当选择到最后一行,且此时num等于0了,只需要进入dfs一次就必须要break出去
dfs(j,num);
if(j==n)
break;
}
flag[i]=0;
}
}
return;
}
int main(){
while(cin>>n>>k&&(n!=-1&&k!=-1)){
for(int i=1;i<=n;i++){
scanf("%s",Map[i]);
}
ans=0;
memset(flag,0,sizeof(flag));
for(int i=1;i<=n-k+1;i++){
dfs(i,k);
}
cout<<ans<<endl;
}
return 0;
}