**
*航电oj:棋盘问题
**
#题目描述
#一般的dfs问题的思路 但要注意附加条件的特殊性
#找位置的时候不必要在两重循环 改位一重循环 结果另存 递归传参为行/列序数
#知识点
dfs
#代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int m;
char mapp[9][9];
int vis[9];//行列上都只有一个 所以一维数组就行了
int ans;
int num = 0;
void dfs(int a)//一行一行找位置 行数
{
if(num == m)
{
ans ++;
return ;
}
if( a >= n)//过界
{
return ;
}
for(int i=0; i<n; i++) ///找位置 列数
{
if(!vis[i]&&mapp[a][i] == '#')
{
num++;//在这一列找到一个了 就不要再考虑这一行的其他了
vis[i] = 1;///标记上 防止重复
dfs(a+1);
num -- ;///dfs 深搜复原基操
vis[i] = 0;
}
}
dfs(a+1);//没有满足上面情况的 找下一行
}
int main()//
{
while(scanf("%d%d",&n,&m)!=EOF)///棋盘边长 要放置的棋子数
{
ans = 0;
num = 0;
memset(vis,0,sizeof(vis));
if(m == -1 && n == -1)
{
return 0;
}
getchar();
for(int i=0; i<n; i++)
{
scanf("%s",&mapp[i]);
}
///for(int i=0;i<=n;i++)
///{
/// printf("%s\n",mapp[i]);
///}
dfs(0);
printf("%d\n",ans);
}
return 0;
}
#总结
按照一般的方法会多一层循环,会超时 利用好所给特殊条件