您的位置:首页 > 其它

深度优先搜索的学习

2016-02-05 14:18 225 查看
解决深度优先搜索关键在于“当下该如何做”到”下一步该如何做“。

通常是把每一种方法都尝试一遍,当这一步解决后进行下一步。

基本模型:

void dfs(int step)
{
判断边界
尝试每一种可萌
for(int i=1;i<=n;i++){
继续下一步
}
返回
}

举例:

输入一个数n,输出1~n的全排列
/*全排列问题,举个例子就是有几张牌放在几个不同盒子里,有多少种情况*/
#include<iostream>
using namespace std;
int a[10], book[10], n;//a是牌,book是盒子,当book为1时说明有牌
void dfs(int step) {
if (step == n + 1) {//当在第n+1和盒子时说明已经排完
for (int i = 1; i <= n; i++) {
cout << a[i];//输出牌
}
cout << endl;
return;//返回上一次调用时的dfs函数
}
for (int i = 1; i <= n; i++) {
if (book[i] == 0) {//判断是否可以放牌
a[step] = i;
book[i] = 1;//标记
dfs(step + 1);//递归,进行下一个盒子
book[i] = 0;//每次放完牌记得要清零
}
}
return;
}
int main() {
cout << "输入盒子个数" << endl;
cin >> n;
dfs(1);//从第一个盒子开始
return 0;
}


再举个例子:

有数字1~9,使得???+???+???=???成立

/*与盒子里放牌是一个道理*/
#include<iostream>
using namespace std;
int a[10], book[10], total = 0;//total是有几种可能
void dfs(int step) {
if (step == 10) {
if (a[1] * 100 + a[2] * 10 + a[3] + a[4] * 100 + a[5] * 10 + a[6] == a[7] * 100 + a[8] * 10 + a[9]) {
total++;
cout << a[1] << a[2] << a[3] << "+" << a[4] << a[5] << a[6] << "=" << a[7] << a[8] << a[9] << endl;
}
return;
}
for (int i = 1; i < 10; i++) {
if (book[i] == 0) {
a[step] = i;
book[i] = 1;
dfs(step + 1);
book[i] = 0;
}
}
return;
}
int main() {
dfs(1);
cout << "一共有" << total << "种可能" << endl;
return 0;
}


利用深度优先搜索走迷宫

/*利用深度优先搜索走迷宫,
输入迷宫时0代表可以走,1代表不能走,
求最短路径*/
#include<iostream>
using namespace std;
int a[51][51];//迷宫
int book[51][51];//用来存储走过的点
int min = 999999;//步数的最小值
int p, q,m,n;
void dfs(int x, int y, int step) {
int next[4][2] = {//行走的坐标
{0,1},//向右
{1,0},//向下
{0,-1},//向左
{-1,0}//向右
};
int next_x, next_y;//下一步的坐标
if (x == p&&y == q) {//判断是否完成
if (step < min)
min = step;//保存最小步数
return;//注意要返回上一次
}
for (int i = 0; i < 4; i++) {//四种走法
next_x = x + next[i][0];
next_y = y + next[i][1];
if (next_x < 1 || next_x>n || next_y < 1 || next_y>m)//判断越界
continue;
if (a[next_x][next_y] == 0 && book[next_x][next_y] == 0) {//判断是否能走
book[next_x][next_y] = 1;//标记走过的点
dfs(next_x, next_y, step + 1);//递归,进行下一步
book[next_x][next_y] = 0;//清零
}
}
return;
}
int main() {
int start_x, start_y;
cout << "输入行和列" << endl;
cin >> n >> m;
cout << "输入迷宫" << endl;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
cin >> a[i][j];
}
cout << "输入起始坐标X" << endl;
cin >> start_x;
cout << "输入起始坐标Y" << endl;
cin >> start_y;
cout << "输入终点坐标X" << endl;
cin >> p;
cout << "输入终点坐标Y" << endl;
cin >> q;
book[start_x][start_y] = 1;//要把起点标记上,防止走重
dfs(start_x, start_y, 0);//起始步数为零
cout << min<<endl;
return 0;
}


如输入:

5 4

0 0 1 0

0 0 0 0

0 0 1 0

0 1 0 0

0 0 0 1

1 1 4 3

结果为 7
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: