<span style="font-size:18px;">方法1</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">#include<iostream>
#include<cstring>
using namespace std;
int k,n;
int viscol[8];
char s[8][8];
int num;
void dfs(int row,int cnt)//row为当前行,cnt为已经放的棋子个数
{
if(cnt==k)
{
num++;
return;
}
if(row>=n)return;//顺序不可颠倒
int j;
for(j=0;j<n;j++)//逐行按列搜索
{
if(s[row][j]=='#'&&!viscol[j])
{
viscol[j]=1;
dfs(row+1,cnt+1);
viscol[j]=0;//回溯,当前棋子的列标记还原
}
}
dfs(row+1,cnt);//逐行搜索,某一行搜索完后从下一行重新搜索。当k<n时,有些多余的行上没有放棋子
}
int main()
{
while(cin>>n>>k&&n!=-1)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
cin>>s[i][j];
}
num=0;
memset(viscol,0,sizeof(viscol));
dfs(0,0);
cout<<num<<endl;
}
return 0;
}
</span>
方法2:
<span style="font-size:18px;">#include<iostream>
using namespace std;
int vis_col[8],vis_row[8];
char s[8][8];
int n,k,num;
void dfs(int row,int cnt)
{
if(cnt==k)
{
num++;
return;
}
if(row>n)return;
for(int i=row+1;i<n;i++)//搜索下一行,遍历所有列
for(int j=0;j<n;j++)
{
if(s[i][j]=='#'&&!vis_row[i]&&!vis_col[j])
{
vis_row[i]=1;vis_col[j]=1;
dfs(i,cnt+1);
vis_row[i]=0;vis_col[j]=0;
}
}
}
int main()
{
int i,j;
while(cin>>n>>k&&n!=-1)
{
num=0;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>s[i][j];
memset(vis_row,0,sizeof(vis_row));
memset(vis_col,0,sizeof(vis_col));
int start_line=n-k+1;//第一颗棋子可能在的行的数目
for(i=0;i<start_line;i++)//逐行搜索,从上到下搜索
for(j=0;j<n;j++)
{
if(s[i][j]=='#')
{
vis_row[i]=1;vis_col[j]=1;
dfs(i,1);//从第i行开始取到一个棋子
vis_row[i]=0;vis_col[j]=0;
}
}
cout<<num<<endl;
}
return 0;
}
</span>