poj 3278 简单BFS多状态搜索

在这里插入图片描述
简单总结为:

在这里插入图片描述

思路:简单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;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43743711/article/details/108058414