简单搜索 dfs 以及 bfs 模板题

         添加摘要                        添加摘要                        添加摘要                        添加摘要           ## bfs(广度优先搜索)模板

迷宫问题
定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

本题使用广度优先算法需使用队列,求最短路径。队列元素可以用pair描述分别代表x,和y坐标。此外需要一个表示各个点到起点距离的二维数组d[][]。可使用memset初始化为-1,当bfs函数返回值为-1时代表无法到达终点。
代码如下:

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int map[5][5]={
0,1,0,1,0,
0,1,0,0,0,
0,0,0,1,0,
0,1,1,1,0,
0,0,0,1,0,
},d[5][5],sx(0),sy(0),ex(4),ey(4);
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
typedef pair<int ,int> P;
void bfs() {
 P p;
 queue<P> que;
 que.push(P(sx,sy));
 d[sx][sy]=0;
 while (que.size()) {
  p=que.front();
  que.pop();
  if (p.first==ex && p.second==ey) break;
  for (int i=0;i<4;i++) {
   int nx=p.first+dx[i];
   int ny=p.second+dy[i];
   if (0<=nx && nx<5 && 0<=ny && ny<5 && map[nx][ny]!=1 && d[nx][ny]==-1) {
    que.push(P(nx,ny));
    d[nx][ny]=d[p.first][p.second]+1;
   }
   }
 }
 return ;
}
int main() {
 memset(d,-1,sizeof(d));
 bfs();
 cout<<d[4][4];
 return 0;
} 

DFS(深度优先搜索)模板

题目:题目:
在一个给定形状的棋盘(形状可能是不规则的)
上面摆放棋子,棋子没有区别。要求摆放时任意
的两个棋子不能放在棋盘中的同一行或者同一列
,请编程求解对于给定形状和大小的棋盘,摆放
k个棋子的所有可行的摆放方案C。

输入含有多组测试数据。 每组数据的第一行是
两个正整数,n k,用一个空格隔开,表示了将
在一个n*n的矩阵内描述棋盘,以及摆放棋子的
数目。 n <= 8 , k <= n 当为-1 -1时表示输
入结束。 随后的n行描述了棋盘的形状:每行
有n个字符,其中 # 表示棋盘区域, . 表示空
白区域(数据保证不出现多余的空白行或者空白列)。

对于每一组数据,给出一行输出,输出摆放的
方案数目C (数据保证C<2^31)。

按行遍历,需要使用一个数组标记该行是否存在棋子,以行数为递归条件,直到行数大于n或者计数器值为m。

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,a[10],tot,cont;
char s[10][10];
void dfs(int cur) {
 if (cont == m) {
  tot++;
  return ;
 }
 if (cur>=n) return ;
 for (int j=0;j<n;j++) {
  if (!a[j] && s[cur][j] == '#') {
   a[j]=1;   /*标记这一列*/
   cont++;   /*计数加一*/
   dfs(cur+1);  /*进入下一行*/
   a[j]=0;   /*被return回来搜索下一列的可能*/
   cont--;   
  }
 }
 dfs(cur+1);/*j遍历完cur行不放棋子*/
}
int main() {
 while (~scanf("%d %d",&n,&m)) {
  if (n==-1 && m== -1) break;
  tot=0;
  cont=0;
  memset(a,0,sizeof(a));
  for (int i=0;i<n;i++) {
   for (int j=0;j<n;j++) {
    cin>>s[i][j];
   }
  }
  dfs(0);
  cout<<tot;
 }
 return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值