搜索问题总结(dfs、bfs的终止条件细节)

题目描述

给定两个-100到100的整数x和y,对x只能进行加1,减1,乘2操作,问最少对x进行几次操作能够得到y?

例如:

a=3,b=11;可以通过3*2*2-1,3次操作得到11;

a=5,b=8;可以通过(5-1)*2,2次操作得到8;

输入描述:

输入以英文逗号分隔的两个数字,数字均在32位整数范围内。

输出描述:

输出一个数字。

示例1

输入

3,11

输出

3

  • BFS:这是一种基于队列这种数据结构的搜索方式,它的特点是由每一个状态可以扩展出许多状态,然后再以此扩展,直到找到目标状态或者队列中头尾指针相遇,即队列中所有状态都已处理完毕。
  • DFS:基于递归的搜索方式,它的特点是由一个状态拓展一个状态,然后不停拓展,直到找到目标或者无法继续拓展结束一个状态的递归。

BFS:对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费量大(需要开大量的数组单元用来存储状态)。 
DFS:对于解决遍历和求所有问题有效,对于问题搜索深度小的时候处理速度迅速,然而在深度很大的情况下效率不高。

DFS代码

#include
using namespace std;
int min_count =0x3ffffff;
bool vis[205];
void solve(int x,int y,int sum){
    if(sum >= min_count) return;    //终止条件和递归出口,变向剪枝;
    //if(x>y) return;              //终止条件{两种情况:x>y,x-100)
            xx = x-1;
        else if(i==2 && x<=55)
            xx = x*2;
        if(!vis[xx+100]){      //这个地方不能加上xx<=y的原因,也可能大于y减1是最优,比如3,11就是如此;
            vis[xx+100]=1;
            solve(xx,y,sum+1);
            vis[xx+100]=0;    //回溯很重要,这是在要到达同一个目标时,要记得回溯;
        }
    }
}
int main(){
    int a,b;
    scanf("%d,%d",&a,&b);
    int sum = 0;
    vis[a+100]=1;
    solve(a,b,sum);
    printf("%d\n",min_count);
    return 0;
}

BFS代码

#include
using namespace std;
int vis[205];
typedef pair pii;
int main(){
    int a,b;
    cin>>a>>b;
    queue q;
    q.push({a,0});
    vis[a+100]=1;
    while(!q.empty()){
        pii u = q.front();
        q.pop();
        if(u.first==b){              //找到目标进行终止;
            cout<=-100 && !vis[xx+100]){
            vis[xx+100]=1;
            q.push({xx,u.second+1});
        }
        xx = u.first*2;
        if(xx<=100 && !vis[xx+100]){
            vis[xx+100]=1;
            q.push({xx,u.second+1});
        }
    }
    return 0;
}

补充

另外附上一份代码,经典搜索题,类似于滑雪和迷宫搜索路径的题目,可以进行对比参考。

搜索问题总结(dfs、bfs的终止条件细节)_第1张图片

你可能感兴趣的:(ACM_笔记)