IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 广度优先算法BFS -> 正文阅读

[数据结构与算法]广度优先算法BFS

广度优先算法必须先定义一个状态结构体,这个结构体包含如内容:

  1. 每走一步需要迭代更新的信息;
  2. 该状态对应的最短步数,一个状态的最短步数存在于它第一次被发现时。

广度优先算法需要用到的数据结构是队列,队列记录每个状态。广度优先算法利用队列先进先出的特性,由一个上一层状态不断扩展出新的下一层状态(上一层的状态比下一层的步数少1)。
在扩展状态的同时,算法每扩展一个新状态,都要探查它是否就是题设的最终状态。
核心代码如下:

       //初始状态
        state a;
        a.x = s;a.y = 0;a.z = 0;a.bushu = 0;
        mark[s][n][m] = 1;
        q.push(a);

		//开始不断扩展
        while(!q.empty()){
        	
            state now = q.front();q.pop();
            int nows,nown,nowm;
            state tmp;  //记录中间状态

            //从一个状态扩展六个新状态,
            //并且探查有没有状态满足题设最终条件
            //s倒n
            nows = now.x;nown = now.y;nowm = now.z;
            AtoB(nows,s,nown,n);
            if(mark[nows][nown][nowm]==false){
                mark[nows][nown][nowm] = true;
                tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
                q.push(tmp);
                //每生成一个新状态,就要进行探查,确定它是否是
                //题目中要找出的最终状态,如果得到最终状态,直接退出搜索
                if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
                    flag = 1;goodbushu = tmp.bushu;break;
                }
            //n倒s
            ...
            //s倒m
            ...
            //m倒s
            ...
            //n倒m
            ...
            //m倒n
            ...
            }
        }

给出例题:
在这里插入图片描述

/*广度优先搜索:利用队列,记录每个状态,并由一个状态不断扩展出新状态*/
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;

int mark[100][100][100];  //记录每个状态是否被标记,已被标记则说明达到了最小步数,不需要操作
struct state
{
    int x,y,z;  //x,y,z各代表三个杯子中所含的饮料量
    int bushu;  //达到这个状态所需的最小步数
};
queue<state> q;  //记录每个状态的队列

void AtoB(int &a,int va,int &b,int vb)  //把A中饮料倒给B,A杯体积为va,B杯体积为vb
{
    if(vb-b>=a){  //b中饮料可以容纳所有a
        b = b+a;
        a = 0;
    }else{  //b中饮料无法容纳所有a
        a = a-(vb-b);
        b = vb;
    }
}

int main()
{
    int s,n,m;
    while(cin>>s>>n>>m && s!=0 && n!=0 && m!=0){
        int flag = 0;  //如果答案为肯定,则flag为1
        int goodbushu = 0;  //若为肯定,则输出最优步数
        while(!q.empty()) q.pop();
        state a;
        a.x = s;a.y = 0;a.z = 0;a.bushu = 0;
        mark[s][n][m] = 1;
        q.push(a);

        while(!q.empty()){
            if(s%2!=0) break;  //奇数直接排除

            state now = q.front();q.pop();
            int nows,nown,nowm;
            state tmp;  //记录中间状态

            //从一个状态扩展六个新状态,并且探查有没有状态满足题设最终条件
            //s倒n
            nows = now.x;nown = now.y;nowm = now.z;
            AtoB(nows,s,nown,n);
            if(mark[nows][nown][nowm]==false){
                mark[nows][nown][nowm] = true;
                tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
                q.push(tmp);
                if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
                    flag = 1;goodbushu = tmp.bushu;break;
                }
            }
            //n倒s
            nows = now.x;nown = now.y;nowm = now.z;
            AtoB(nown,n,nows,s);
            if(mark[nows][nown][nowm]==false){
                mark[nows][nown][nowm] = true;
                tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
                q.push(tmp);
                if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
                    flag = 1;goodbushu = tmp.bushu;break;
                }
            }
            //s倒m
            nows = now.x;nown = now.y;nowm = now.z;
            AtoB(nows,s,nowm,m);
            if(mark[nows][nown][nowm]==false){
                mark[nows][nown][nowm] = true;
                tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
                q.push(tmp);
                if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
                    flag = 1;goodbushu = tmp.bushu;break;
                }
            }
            //m倒s
            nows = now.x;nown = now.y;nowm = now.z;
            AtoB(nowm,m,nows,s);
            if(mark[nows][nown][nowm]==false){
                mark[nows][nown][nowm] = true;
                tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
                q.push(tmp);
                if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
                    flag = 1;goodbushu = tmp.bushu;break;
                }
            }
            //n倒m
            nows = now.x;nown = now.y;nowm = now.z;
            AtoB(nown,n,nowm,m);
            if(mark[nows][nown][nowm]==false){
                mark[nows][nown][nowm] = true;
                tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
                q.push(tmp);
                if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
                    flag = 1;goodbushu = tmp.bushu;break;
                }
            }
            //m倒n
            nows = now.x;nown = now.y;nowm = now.z;
            AtoB(nowm,m,nown,n);
            if(mark[nows][nown][nowm]==false){
                mark[nows][nown][nowm] = true;
                tmp.x=nows;tmp.y=nown;tmp.z=nowm;tmp.bushu=now.bushu+1;
                q.push(tmp);
                if((nowm==s/2&&nown==s/2) || (nowm==s/2&&nows==s/2)||(nown==s/2&&nows==s/2)){
                    flag = 1;goodbushu = tmp.bushu;break;
                }
            }
        }
        if(flag!=1){
            cout<<"NO"<<endl;
        }else{
            cout<<goodbushu<<endl;
        }
    }
}
/*
输入:
4 1 3
输出:
3
*/

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-16 11:33:17  更:2021-07-16 11:35:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 17:54:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码