深度优先搜索的学习

19 篇文章 1 订阅
11 篇文章 0 订阅

解决深度优先搜索关键在于“当下该如何做”到”下一步该如何做“。

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

基本模型:

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值