添加摘要 添加摘要 添加摘要 添加摘要 ## 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;
}