dfs(深度优先搜索)
bfs(广度优先搜索)
作为初学者,可能会想,搜索吗,就是作用在图上啊,树上什么的算法。其实,搜索(这里主要说dfs和bfs),就是以一种特定方式,在大多数场景寻找真正想要结果的方式。而dfs就是以一种现已一种单一方式走到黑,然后通过回溯等得到答案的过程。而bfs则是先看有多少种方式可以走,然后先记录每一种方式,在一一按这种方式一层一层遍历,直到得到最后结果。这两种搜索大体上没什么差别,都是搜索出所有可能满足自己的答案而已。有的人可能会说,bfs适合求最短路径,dfs适合求所有答案,其实,两个都可以相互转化(这里不多说,其实我也不怎么懂,哈哈~),只不过方便与否的问题罢了。
下面就对这两种经典搜索进行简单探讨。
模板:
void bfs(){
if:(...){//需要的结果
...
//做出操作
return;//结束
}
...
dfs();
...//具体要怎么搜索
}
这就是走到黑方式,就像对123进行全排列,123,132,213,231,312,321;
按照顺序排列就是方式,然后逐个改变。
多说这种无益,来一道最简单的bfs的题目吧:
有一款游戏叫做《绝地求生:大逃杀》。
绝地求生,是一款开放世界策略射击游戏,采用虚幻4引擎制作。 是一款大逃杀类型的游戏,每一局游戏将有100名玩家参与,他们将被投放在绝地岛(battlegrounds)的上空,游戏开始跳伞时所有人都一无所有。 游戏展开的方式是:玩家赤手空拳地分布在岛屿的各个角落,利用岛上多样的武器与道具。 随着时间的流逝,岛上的安全地带越来越少,特定地区也会发生轰炸的情况,最终只有一人存活获得胜利。游戏的每一局比赛都会随机转换安全区,这样玩家的很新鲜与紧张感会更加强烈。
小东同学玩游戏也坚决不忘算法的学习,有一天,他面临了这样的情况,小东要前往安全区,他决定冒险通过一片大平原,虽然跑向两边的山上更安全,但是时间来不及了。在小东同学奔跑的过程中,浑然不知两边的山上各有一个人趴在那里埋伏猎物,他们同时发现小东,同时开枪!小东意识到危险了!伴随了若干声枪声,砰砰砰!小东已经倒地了...
小东挂掉之前一秒,意识到了一件事,两边的人同时开枪,那么我又多少种中弹顺序呢?比如我有100血,而一个人用冲锋枪每发子弹能伤害我30血,另一个人用步枪每发子弹能伤害我45血,那导致我死亡的中弹顺序可能是,30 30 30 45,也可能是 45 45 30,也有可能是45 30 45,等等。当然,血量小于或等于0都算被击倒。
同时要注意,如果两人每次对自己造成的伤害是相同的,但仍被看作不同的死亡顺序,比如玩家有100血量,左右两边的人每次能造成50血量的伤害,那么答案为4,情况分别为:
50 50(左边敌人打中了两枪)。
50 50(右边敌人打中了两枪)
50 50(左边敌人开了第一枪)
50 50(右边敌人开了第一枪)
本题有多组测试数据。每组占一行,由三个正整数m n hp组成(10=
对于每组输入数据,输出一行,结果为玩家有多少种死亡顺序,即中弹顺序。
45 30 100
50 50 100
12 23 80
9
4
34
思路:看题意是求出所有方式,所以用dfs比较方便,然后,走到黑,先以第一种方式减血(第一个例子,-45,-45,-45。。。),然后就回溯,继续操作,看代码:
//绝地求生之死亡顺序
#include
using namespace std;
int ans=0,l,r,hp;
void dfs(int hp,int l,int r){
if(hp<=0){
ans++;
return;
}
dfs(hp-l,l,r);
dfs(hp-r,l,r);
}
int main(){
while(cin>>l>>r>>hp){
dfs(hp,l,r);
cout<
下面就来看bfs:
模板:
void bfs(){
if(){
return;//首先判断当前位置是否为结果
}
while(){
...//循环每一种方试直到最后的结果
}
return ;
}
对于bfs,用得最多的试队列,来插入(记录方法)与弹出(此方法遍历完毕)来进行搜索, 最经典的迷宫问题(求最短路径):
时间限制: 1 Sec 内存限制: 128 MB
题目描述
老王同学深陷一个迷宫,他现在想要逃出去。迷宫 是这样的,在m行n列的矩阵当中,“.”表示可以通过的道路,“#”表示墙,是障碍物所以不能通过。迷宫中S代表起始点,E代表出口。老王每次只向上、向下、向左、向右移动一个单位距离,每次移动一个距离话费的时间是1分钟。请问老王最少花多少时间可以离开迷宫,或者根本就不能离开迷宫?
输入
本题有多组测试数据,对于每组测试数据:
两个整数mn表示m行n列的迷宫,0
接下来是m行n列的迷宫,其中S表示入口,E表示出口,#表示墙,.表示通路。
输出
如果老王逃出去话费X分钟,则输出:
Escaped in x minute(s).
如果老王不能逃出去,则输出:
Trapped!
样例输入
3 3
S..
.#.
..E
3 3
S#.
.#.
.#E
样例输出
Escaped in 4 minute(s).
Trapped!
思路也不必多说,搜索所有路径,找到最短的,代码如下:
#include
#include
#include
using namespace std;
char map[101][101];
int n,m;
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int v[101][101],d[101][101];
queue q;
void bfs(int x,int y){
while(q.size()){
char tq=q.front();
q.pop();
if(tq=='E')
break;
for(int i=0;i<4;i++){
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(map[tx][ty]=='.'&&v[tx][ty]==0&&tx>=0&&tx=0&&ty>map[i][j];
if(map[i][j]=='S'){
sx=i;
sy=j;
q.push(map[i][j]);
v[i][j]=1;
}
if(map[i][j]=='E'){
ex=i;
ey=j;
}
}
bfs(sx,sy);
if(d[ex][ey]==0)
cout<<"Trapped!"<
可能会有错哦,好久以前写的,不知道是对的还是错的,但知道方式与思路就行!
其实dfs与bfs都大相径庭,所以,当你用熟练了,几乎都能互用,只是代码多少的问题而已!