简单总结为:
思路:简单BFS
将a放入队列中,如果队列不空,就取出队头,分析三种情况,如果没被访问过就将新的a放入队列,直到取出的队头等于b,返回查找的次数。
也可以认为是一棵度为3的树,因为有三个操作,但是这个得剪枝,不然会超时
也就是设置一个数组或者unordered_set,只要数组里面对应的值是true或者set容器里面存在,那么我们就不放进队列当中。
如图:
//这是第一种写法,还有另外一种写法,两种写法原理是一样,
//只不过代码不一样,个人推荐第二种写法
# include <iostream>
# include <queue>
using namespace std;
const int N = 1e5+10;
int q[N];
struct node{
int w,step;
};
int n,m;
node t[N];
int bfs(int n,int m){
if(n==m)
return 0;
int head=1,tail=1;
t[tail].w=n;
t[tail].step = 0;
++tail;
q[n]=1;
while(head<tail){
node h ;
for(int i=1;i<=3;++i){ //因为三种操作
h = t[head];
switch(i){
case 1 : h.w++;break;
case 2 : h.w--;break;
case 3 : h.w*=2;break;
}
if(h.w>=0 && h.w<=N && q[h.w]==0){
q[h.w]=1;
h.step = t[head].step+1;
t[tail++] = h ;
if(h.w==m){
return h.step;
}
}
}
++head;
}
}
int main(void)
{
cin>>n>>m;
cout<<bfs(n,m)<<endl;
return 0;
}
力扣 1553. 吃掉 N 个橘子的最少天数
思路:还是跟上面的题目一样的思路,只不过这里的写法有点不一样,个人推荐这种写法,更明确。
class Solution {
public:
int minDays(int n) {
unordered_set<int> st;
st.insert(n);
int ans = 0;
queue<int> q;
q.push(n);
while(q.size()){
int len = q.size();
for(int i=1;i<=len;++i){
int t = q.front();
q.pop();
// cout<<t<<'*'<<' ';
if(t==0) return ans;
if(st.find(t-1) == st.end() ){
st.insert(t-1);
q.push(t-1);
}
if(t%2==0 && st.find(t/2)==st.end()) {
st.insert(t/2);
q.push(t/2);
}
if(t%3==0 && st.find(t - 2*(t/3))==st.end() ){
st.insert(t - 2*(t/3));
q.push(t - 2*(t/3));
}
}//cout<<endl;
++ans;
}
return 0;
}
};