题目描述
给定两个-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<bits/stdc++.h>
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<y都有可能},因为有-1的操作,就会一直减1陷入死循环;
//printf("%d %d\n",x,y);
if(x==y){
min_count = min(min_count,sum); //递归的出口;
return;
}
int xx;
for(int i =0;i<3;i++){
if(i==0 && x<100)
xx = x+1;
else if(i==1 && 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<bits/stdc++.h>
using namespace std;
int vis[205];
typedef pair<int,int> pii;
int main(){
int a,b;
cin>>a>>b;
queue<pii> q;
q.push({a,0});
vis[a+100]=1;
while(!q.empty()){
pii u = q.front();
q.pop();
if(u.first==b){ //找到目标进行终止;
cout<<u.second<<endl;
return 1;
}
int xx;
xx = u.first+1;
if(xx<=100 && !vis[xx+100]){
vis[xx+100]=1;
q.push({xx,u.second+1});
}
xx = u.first-1;
if(xx>=-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;
}
补充
另外附上一份代码,经典搜索题,类似于滑雪和迷宫搜索路径的题目,可以进行对比参考。