又又又又是一道递归题
我第一反应是类似于N皇后问题的递归,但后来发现不太一样,因为棋盘的可存在不放棋子的一行。
先来看看题目叭
题目链接:棋盘问题
问题描述![在这里插入图片描述](https://img-blog.csdnimg.cn/20200222000235192.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0Rvcm9f,size_16,color_FFFFFF,t_70)
对于上面两个样例,答案分别为1、2.
注意
1、由于棋盘不规则,加上放的棋子数与棋盘行数并不相同,所以可存在不放棋子的一行。
2、此题不能像皇后问题一样,dfs假设为前k-1行都排好,因此我们要使用一个变量记录放好棋子数目。
3、不能存在棋子在相同列,可用一个数组记录,注意这里可以直接用数组下标代替第几列,当数值与初始不同时证明这一列已放棋子。(不需要记录每一行所放的列数)
代码实现
#include<stdio.h>
#include<string.h>
char m[9][9];
int n,k,ans=0,flag[9]={0},cnt=0;
void dfs(int h){//放置第h行
int i,j;
if(cnt==k){//棋子已经放完,方案数目增加
ans++;
return ;
}
if(h>=n) return ;//超过棋盘范围
for(j=0;j<n;j++){//找h行中符合位置
if(m[h][j]=='#'&&flag[j]==0){//注意看此列是否已放置
flag[j]=1;//标记
cnt++;//已放棋子数增加
dfs(h+1);//放h+1行
cnt--;//回溯后棋子数目减少
flag[j]=0; //取消标记
}
}
dfs(h+1);//在h行不放棋子,在h+1行尝试
}
int main()
{
while(scanf("%d %d",&n,&k)!=EOF&&n!=-1&&k!=-1){
getchar();
int i;
for(i=0;i<n;i++){
gets(m[i]);
flag[i]=0;
}
ans=0;//方案初始化
cnt=0;//已放棋子初始化
dfs(0);
printf("%d\n",ans);
}
return 0;
}
加油加油!