dfs模板题
直接上代码及分析
#include <iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
ll n,k,qz=0,cnt=0;///qz棋子数,cnt方案数
int visit[10];///第i列是否有放棋子
char a[15][15];
void dfs(ll l)
{
if(qz==k) {cnt++; return ;}///但是要先判断棋子数是否够了,再判断行数是否到了,
///因为若是加上最后一行棋子数达到了k,l+1=n停止了而cnt没加1
if(l>=n) return;///return 即不再执行下面语句,
for(int i=0;i<n;i++)///dfs这行一有可以放的棋子就到下一行搜索
{
if(a[l][i]=='#'&&visit[i]==0)
{
qz++,visit[i]=1;
dfs(l+1); ///不断的递归到下一行,有就继续向下搜索
visit[i]=0;///将最后放上去的棋子拿起来,是一个一个拿起来的
qz--; ///将最后放上去的棋子拿起来,否则之前放的棋子没拿起来会对后面的情况造成影响
///例子:假如第0行有两个# 当从第0行的第一个#开始往下走时,假设第2行中有且只有一个#,并且不与第一行中的任意一个在同一列,那么在往下
///走时就会把这个#标记 当递归返回到第一行第一个#时 i会++ 到第一行的第2个# 函数继续会继续往下走 ,到达第2行的那个#,因为在第一行第一个#那条路径中
///已经走过了第2行的那个#(因为第2行只有一个#并且这个#所在的列数不与第一行两个#重合),如果不把第一次走过第二行的#的标记消除 那么这次路径就不会再过第二行的
///这个# 那么可选路径少了 肯定不对了
}
}
dfs(l+1);///若第l行没有符合条件的格子,那么往下下一行搜索
}
int main()
{
while(cin>>n>>k&&n!=-1)
{
for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>a[i][j];
dfs(0);
cout<<cnt<<endl;
cnt=0;qz=0;
memset(visit,0,sizeof(visit));
}
}