题目:http://poj.org/problem?id=1321
要求:在给定的棋盘上可以摆放的规定棋子的方法数。
DFS:假如我从 0个棋子开始寻找可以摆放的位置
有些点我无法访问:
1、本身不能放置棋子的点,比如"."
2、一列上只允许出现一个棋子,意味着要对访问过的列号进行标记。
3、针对BFS 我要这是一个递归终止条件,以使其结束返回。
下面是我学习的BFS 算法:https://www.cnblogs.com/ECJTUACM-873284962/p/6747947.html
#include<iostream>
#include<cstring>
using namespace std;
int cnt;
int k;
int n ;
char a[1000][1000];
bool colomn[10000];
int BFS(int x ,int y){ //y这里表示 是否达到k个棋子
if(y==k){
cnt++;
return 0;
}
for(int i = x; i < n ; ++i){
for(int j = 0 ; j < n ;++j){//列的循环条件
if(a[i][j] == 1 && colomn[j] == true ){ //可以摆放棋子,而且还没有在这一列没有访问
// BFS(x+1,y);//这一行我不放棋子
colomn[j] = false ; //标记这一列
BFS(i+1,y+1);
colomn[j] = true ; //更新这一列 及时归还原来的值,我理解的不是很具体
}
}
}
return 0 ;
}
int main(){
while(cin >> n >> k){
if(n==-1 && k== -1){
break;
}
cnt = 0 ;
memset(colomn,true,sizeof(colomn));
for (int i = 0 ;i < n;++i){//预处理 ,起初是在全局变量初始化的地方初始化为true,
//实际上每次开始之前我要是其中的值都为true
for (int j = 0;j < n; ++j){
cin >> a[i][j];
if(a[i][j]=='#'){
a[i][j] = 1;
}
else {
a[i][j] = 0;
}
}
}
BFS(0,0);
cout << cnt <<endl;
}
return 0;
}
递归的算法也很好理解,利用二层循环进行逐个元素点的遍历,如果在可以摆放棋子的情况下再次判断是否已经在列出现过。(利用bool类型的数组标记) 递归进行下一行的搜索。
当你遍历下一行的时候代表不在同一行上了,就只要遍历列就可以了.
个人总结:
一般求解迷宫出路的问题用BFS会比较快,BFS会把下一阶段所有可行解标记。
这里的话是一定只能向下一行走是已经明确的,所以用DFS 进行深层查找。