分酒问题(BFS或DFS)

【数据结构】图的遍历:广度优先(BFS),深度优先(DFS) 算法思想,广度优先生成树,深度优先生成树,算法实现 阅读详情

      

      已知有三个容量分别为1斤、7两和3两的并且是没有刻度的酒瓶,1斤的瓶子装满了酒,而7两和三两的瓶子为空。现要求将这些酒分出5两出来。


BFS:

#include<iostream>  
#include<stdio.h>  
#include<map>  
#include<vector>  
#include<queue>  
#include<set>  
#include<cstdlib>  
#include<string.h>  
#include<algorithm>  
#include<cmath>  
#define MAXN 1000010  
#define EPS 1e-9  

using namespace std;

struct node{
	int a;//对应容量为一斤的瓶子里当前所装的酒量 
	int b;//对应容量为七两的瓶子里当前所装的酒量 
	int c;//对应容量为三两的瓶子里当前所装的酒量 
	int pre;//父节点id 
	int id;//节点id 
	string str;//记录该状态对应的操作 
}state[1000010];

int vis[100][100][100];
int cnt;
int num;
int ids[1000];

/**************************************** 
BFS函数说明:枚举各种倒满方案,依次进行广搜
参数:v1,v2,v3依次为瓶子容量,a,b,c为所装酒量,x为要称出的酒量    
********************************************/   
int BFS(int v1,int v2,int v3,int a,int b,int c,int x)
{
	int fg=-1; 
	num=0;
	queue<node>q;
	memset(vis,0,sizeof(vis));
	node cur,nex;
	cur.a=a;
	cur.b=b;
	cur.c=c;
	cur.str="";
	cur.pre=cur.id=0;
	q.push(cur);
	vis[a][b][c]=1;
	cnt=0;
	state[cnt]=cur;
	while(!q.empty())
	{
		cur=q.front();
		q.pop();
		if(cur.a==x||cur.b==x||cur.c==x)//找到解 
		{
			fg=1;
			ids[++num]=cur.id;
			continue;
			//return cur.id;
		}
		else
		{
			//1斤倒满7两
			if(cur.a!=0 && cur.b!=v2)
			{
				nex.str="a->b ";
				if(cur.a+cur.b <= v2)
				{
					nex.a=0;
					nex.b=cur.b+cur.a;
					nex.c=cur.c;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
				else
				{
					nex.a=cur.b+cur.a-v2;
					nex.b=v2;
					nex.c=cur.c;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
			}
			//7两倒满1斤
			if(cur.a!=v1 && cur.b!=0)
			{
				nex.str="b->a ";
				if(cur.a+cur.b <= v1)
				{
					nex.b=0;
					nex.a=cur.b+cur.a;
					nex.c=cur.c;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
				else
				{
					nex.b=cur.b+cur.a-v1;
					nex.a=v1;
					nex.c=cur.c;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}	
			}
			//1斤倒满3两
			if(cur.a!=0 && cur.c!=v3)
			{
				nex.str="a->c ";
				if(cur.a+cur.c <= v3)
				{
					nex.a=0;
					nex.c=cur.c+cur.a;
					nex.b=cur.b;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
				else
				{
					nex.a=cur.c+cur.a-v3;
					nex.c=v3;
					nex.b=cur.b;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
			}
			//3两倒满1斤
			if(cur.a!=v1 && cur.c!=0)
			{
				nex.str="c->a ";
				if(cur.a+cur.c <= v1)
				{
					nex.c=0;
					nex.a=cur.c+cur.a;
					nex.b=cur.b;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
				else
				{
					nex.c=cur.c+cur.a-v1;
					nex.a=v1;
					nex.b=cur.b;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
			}
			//7两倒满3两
			if(cur.b!=0 && cur.c!=v3)
			{
				nex.str="b->c ";
				if(cur.b+cur.c <= v3)
				{
					nex.b=0;
					nex.c=cur.c+cur.b;
					nex.a=cur.a;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
				else
				{
					nex.b=cur.c+cur.b-v3;
					nex.c=v3;
					nex.a=cur.a;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
			}
			//3两倒满7两
			if(cur.c!=0 && cur.b!=v2)
			{
				nex.str="c->b ";
				if(cur.b+cur.c <= v2)
				{
					nex.c=0;
					nex.b=cur.c+cur.b;
					nex.a=cur.a;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
				else
				{
					nex.c=cur.c+cur.b-v2;
					nex.b=v2;
					nex.a=cur.a;
					if(!vis[nex.a][nex.b][nex.c])
					{
						nex.pre=cur.id;
						cnt++;
						nex.id=cnt;
						state[cnt]=nex;
						q.push(nex);
						vis[nex.a][nex.b][nex.c]=1; 
					}
				}
			}
		}
	}
	return fg;//无解 
}

int path[1000000];
void track(int id)//倒推得到分酒步骤 
{
	
	int num=0;
	int i=id;
	int j;
	path[++num]=i;
	while(state[i].pre!=i)
	{
		i=state[i].pre;
		path[++num]=i;
	}
	for(j=num;j>=1;j--)
	{
		cout<<state[path[j]].str ;
	}
	puts("");
}

int main() 
{	
	int a,b;
	int t=BFS(10,7,3,10,0,0,5);
//	printf("%d\n",t);
    if(t!=-1)
    {
    	for(int i=1;i<=num;i++)
    	{
    		printf("第%d种分酒方案如下:\n",i); 
			track(ids[i]);
		}
	}
	else
	{
		printf("无解\n"); 
	}    
	return 0;
}



DFS:

#include<iostream>  
#include<stdio.h>  
#include<map>  
#include<vector>  
#include<queue>  
#include<set>  
#include<cstdlib>  
#include<string.h>  
#include<algorithm>  
#include<cmath>  

using namespace std;

int vis[100][100][100];

char path[100000][2];

int cnt=0;

void dfs(int a,int b,int c,int step)
{
	if(a<0 || b<0 || c<0 || a>10 || b>7 || c>3 || vis[a][b][c])
		return;
	vis[a][b][c]=1;
	if(a==5 || b==5 || c==5)
	{
		cnt++;
		printf("第%d种分酒方案如下:\n",cnt);
		for(int i=1;i<step;i++)
		{
			printf("%c->%c ",path[i][0],path[i][1]);
		}
		puts("");
		vis[a][b][c]=0;
		return;
	}
	else
	{
		//1斤倒满7两
		path[step][0]='a';
		path[step][1]='b';
		dfs(0,a+b,c,step+1);	
		dfs(a+b-7,7,c,step+1);
		
		//7两倒满1斤
		path[step][0]='b';
		path[step][1]='a';
		dfs(a+b,0,c,step+1);
		dfs(10,a+b-10,c,step+1);
		
		//1斤倒满3两
		path[step][0]='a';
		path[step][1]='c';
		dfs(0,b,a+c,step+1);
		dfs(a+c-3,b,3,step+1);
		
		//3两倒满1斤
		path[step][0]='c';
		path[step][1]='a';
		dfs(a+c,b,0,step+1);
		dfs(10,b,a+c-10,step+1);
		
		
		//7两倒满3两
		path[step][0]='b';
		path[step][1]='c';
		dfs(a,0,b+c,step+1);
		dfs(a,b+c-3,3,step+1);
		
		//3两倒满7两
		path[step][0]='c';
		path[step][1]='b';
		dfs(a,b+c,0,step+1);
		dfs(a,7,b+c-7,step+1);
	}
} 

int main() 
{	
	memset(vis,0,sizeof(vis)); 
	dfs(10,0,0,1);  
	return 0;
}



什么时候用BFS,什么时候用DFS?BFS与DFS应用场景 1 前言 最近做到一道 找迷宫中从入口到出口最短路径的一道题。 力扣-找到离入口最近的出口 显然,理论上DFS和BFS都能找到解。 但是,DFS会超时,BFS就不会。 因此,我就又研究了一下DFS和BFS的原理,整理了一下他们的应用范围,希望自己能记住,刷题的时候少走弯路。 2 原理 2.1 BFS 宽度优先搜索算法(又称广度优先搜索) 形象地说:面临一个路口时,把所有的岔路口都记下来,然后选择其中一个进入,然后将它的分路情况记录下来,然后再返回来进入另外一个岔路 队列(queue)实现:每次从队 阅读详情

相关推荐

深度优先算法和广度优先算法

今天做了daoti

solar一抹阳光的专栏 8441

泊松分酒问题

著名数学家研究过一个有趣的数学问题:某人有12品脱的啤酒一瓶,想从中倒出6品脱,但他没有6品脱的容器,仅有一个8品脱和一个5品脱的容器,怎样才能将啤酒分成两个6品脱呢?其意义是:从12脱的瓶中向8脱的瓶中倒x次,并且将5品脱瓶中的酒向12的瓶中倒y次,最后在12品脱的瓶中剩余6品脱的酒。分别用a、b、c代表12品脱、8品脱和5品脱的瓶子,求出不定方程的整数解,按照不定方程的意义,则倒酒法为:a→b→c→a。依次输入,满瓶的容量 ,第一个空瓶的容量 ,第二个空瓶的容量 ,平分后每个杯子中的品脱数。

2302_76596737的博客 758

迷宫问题中的DFS和BFS

迷宫问题与深搜和广搜 文章目录****迷宫问题与深搜和广搜****前言一、深度优先算法1)简介2)实例---->迷宫问题3)深搜的缺点二、广度优先搜索1)简介2)实例---->迷宫问题3)广搜的优缺点 前言 搜索算法是一种较为常见且基础的算法 最新在做迷宫问题的时候学习了深度优先搜索和广度优先搜索 写一个博客来总结一下 也方便以后自己复习 提示:以下是本篇文章正文内容,下面案例可供参考 一、深度优先算法 1)简介 深度优先算法(Depth-First-Search),可以简称为DFS,

qq_50857039的博客 1838

一般化分酒问题的所有求解(C代码)

DFS 在分酒问题上面,用DFS解决我个人认为是不太好的。主要是因为无法很好地控制一个往回代的过程,也就是如果不仔细加以控制,甚至于即便加以控制,总是有那么一点不确定性将会让程序崩溃。而且在求出解的方面可能会出现比较多的重复解。。我研究了几天的DFS,由于水平原因,还是不得不放弃。改用BFS。 BFS 整体来讲,BFS的算法还算简单化,并且比较容易理解。。废话不多说直接上代码了 (ps:我里面使用...

qq_31630929的博客 813

数学建模分酒问题

分酒问题

大学生数学建模大赛——分酒问题

论文是分酒问题的C语言程序及详细步骤说明,因此对于数学建模学习非常有用

一个分酒问题的求解

 一个分酒问题的求解流浪狗 2005.3 这是大部分人都玩过的智力问题,有两个容量为8斤的酒瓶装满酒,另有一个三斤的空酒瓶,利用这三个没有标度的酒瓶将这些酒分给四个人喝,每个人分4斤酒。可能我们也很早的时候就已经得出了正确答案了!可是,我要说的是这的却是一个很有意思的问题,尤其是今天我想用计算机去实现这个问题的解时。可能,接触过游戏的人工智能编程的朋友对这种问题一定不会陌生,因为这跟比如说象棋或者

流浪狗之家 3442

USB3.0一致性测试方案

为各测试项目具体测试结果包括脉冲串突发时间、脉冲串重复时间、时钟周期以及眼图等完整USB3.0测试项目,工程师可以看到各项测试的具体结果方便观察。RIGOL 提供了一套完善的工具,包括数字示波器、专业的测试夹具以及全自动一致性测试软件,使得USB 3.0设备设计人员能够高效精确地进行信号捕捉、测试与分析。报告第二部分测试摘要,在此可以看到USB3.0测试所有测试项目,并且可以观看到测试是否正常,可以帮助工程师更好的判断测试结果。,以简化下载、存储以及对于多媒体的大量内容的共享。

2409_87378937的博客 2530

泊松分酒

泊松分酒是一个著名的智力测试题,也是一个有难度的过程模拟经典案例;1.案例提出:法国数学家泊松(Poisson)曾提出以下分酒趣题: 某人有一瓶12品脱(容量单位)的酒,同时有容积为5品脱与8品脱的空杯各一个,借助这两个空杯,如何将这瓶12品脱的酒平分? 我们要解决一般的平分酒案例: 借助容量分别为bv与cv(单位为整数)的两个空杯,用最少的分倒次数把总容量为偶数a的酒平分,这里正整数bv、cv与偶

double_main的博客 2962

Multisim14安装失败?手把手教你彻底清理残留文件(附专用卸载工具)

本文针对Multisim14安装失败问题,提供了一套从根源解决的完整方案。文章详细分析了安装失败的三大元凶——文件残留、注册表残留和隐藏组件,并手把手指导用户使用专用卸载工具进行标准化清理,再结合手动深度清理文件系统和注册表,最终实现彻底卸载和完美重装,有效解决Multisim14安装问题。

weixin_29179311的博客 317

【3D目标检测】环境搭建(OpenPCDet、MMdetection3d、Det3d)

在Conda虚拟环境中搭建MMdetection3d环境

qq_44703886的博客 4252

蓝桥-分酒问题

3. 分酒问题 有4个红酒瓶子,它们的容量分别是:9升, 7升, 4升, 2升 开始的状态是 [9,0,0,0],也就是说:第一个瓶子满着,其它的都空着。 允许把酒从一个瓶子倒入另一个瓶子,但只能把一个瓶子倒满或把一个瓶子倒空,不能有中间状态。 这样的一次倒酒动作称为1次操作。 假设瓶子的容量和初始状态不变,对于给定的目标状态,至少需要多少次操作才能实现? 本题就是要求你编程实现最小操作次数的...

无 929

rfid标签技术原理

奇怪的是,RFID标签技术原理的深入剖析不仅揭示了其背后的奥秘,也让我们更加全面地认识到这一技术在数字化转型中的重要性和潜力。随着技术的不断进步和应用场景的不断拓展,RFID标签将在更多领域发挥重要作用,为物联网、智能制造等领域的发展注入新的活力。这意味着在一个读写器的覆盖范围内,可以同时读取多个RFID标签的数据,大大提高了数据收集的速度和效率。:RFID标签的“大脑”,负责存储和处理数据。芯片内部集成了存储器、控制逻辑和射频接口等电路,能够接收来自读写器的射频信号,执行相应的数据处理和通信任务。

x3088的博客 2159

【算法+城堡问题、迷宫问题】BFS(广度优先)和DFS(深度优先)

判断顶点1是否被访问,如未访问过,就见标记数组中顶点1对应的值改为true,将顶点1入队,再判断顶点2是否被访问,重复上述操作,将2入队。再通过矩阵找到顶点1的邻接顶点0、3,顶点0的访问标记数组为true,说明被访问则不再重复访问,继续判断3是否被访问过,未访问就将标记数组的值改为true,将3入队,队列不为空则将队头元素2出队。首先访问节点0,将数组0对应的位置改为true,表示已经访问过,再将顶点0进行入队操作,再判断队列是否为空(当前有顶点0不为空),将队列的对头元素0进行出队。

2302_82116250的博客 2266

基于价值的深度强化学习:DQN

本文主要是介绍DQN原理和算法伪代码和代码实现,算法实现包括pytorch版本和stable-baselines3版本

溯源的专栏 1085

ROS四旋翼无人机快速上手指南(4):阿木实验室PX4功能包飞行控制分析与讲解(重点章节)

成就更好的自己 这一章详细讲解一下阿木实验室(AMOV)的开源项目px4_command功能包,此功能包通过mavlink协议直接控制烧录px4固件的自驾仪,还融合了来自各个传感器的位姿,距离等信息,此外,功能包提供的接口向上对接应用层算法级的程序例如SLAM,kfc目标检测引导,路径规划等算法,因此,在整个无人机控制中起到了承上启下至关重要的作用。 用到的文件及工具包链接如下: AMOV实验室源码如下: https://gitee.com/theroadofengineers/px4_comman

The Road of Engineer 6171

深度优先算法(DFS)

根据访问节点的顺序与方式,可以分为广度优先算法(BFS)和深度优先算法(DFS),本文介绍深度优先算法: 深度优先算法 1、算法概述 深度优先搜索属于图算法的一种,英文缩写为DFS。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。 深度优先搜索是一种在开发爬虫早期使用较多的方法,它的目的是要达到被搜索结构的叶结点(即那些不包含任何超链的HTML文件) 。 它的...

qq_41896683的博客 3万+

CMOS Sensor的调试经验分享

我这里要介绍的就是CMOS摄像头的一些调试经验。 首先,要认识CMOS摄像头的结构。我们通常拿到的是集成封装好的模组,一般由三个部分组成:镜头、感应器和图像信号处理器构成。一般情况下,集成好的模组我们只看到外面的镜头、接口和封装壳,这种一般是固定焦距的。有些厂商只提供芯片,需要自己安装镜头,镜头要选择合适大小的镜头,如果没有夜视要求的话,最好选择带有红外滤光的镜头,因为一般的sensor都...

camerall 3763

DFS、BFS 算法

DFS使用递归方式遍历节点,而BFS则利用队列实现节点的逐层访问。通过辅助数组记录已经访问的节点,避免重复访问,并最终完成整个图的遍历。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 9131

基于FPGA的数字信号处理(11)--定点数的舍入模式(2)向最临近值取整nearest

基于FPGA的数字信号处理(11)--定点数的舍入模式(2)向最临近值取整nearest

孤独的单刀 5475

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

迷宫问题-DFS-BFS

迷宫问题的DFS-BFS 解决迷宫最短路径问题 和迷宫所有路径问题

Djsnxbjans的博客 1350

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

DFS (深度优先算法)

DFS(深度优先搜索算法):一种用于遍历或者树或者图的算法,是一种递归程序,不断递归达到无法在到达的点,简单点来说:一条路一直走,走到没有路后就原路返回,重新选择另一条 dfs(step + 1)。 DFS = 暴搜 + 回溯算法 + 剪枝(大多数是这样)。DFS需要回溯算法,其他算法也需要回溯算法,两种是一种调用关系。 暴搜:一条路走到黑(直接递归走到底) 回溯:DFS开启另一条路则需要回溯,如果暴搜那条路找不到答案就要回溯走另外一条道路。 剪枝:如果明确接下来的搜索找不到答案或者不是最优解,就

qq_46056407的博客 4730

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

LeetCode琅琊榜第十三层-全排列(DFS深度优先算法)

LeetCode.46全排列 难度:中等 博主空间与往期力扣 题目链接

算法萌新一枚 804

一文带你了解dfs和bfs算法

一文带你了解dfs和bfs算法 如上图,dfs和bfs算法通常会用来解决迷宫问题,两种算法都可以找到一条通往重点的路,但又有不一样的地方。 体验地址:http://120.79.163.94/demo/寻路算法.html 可以自己定义迷宫是否可走,及起始点和终点。 深度优先算法(dfs) 简介 dfs算法又称深度优先搜索,是计算机术语。 1、dfs是一种在开发爬虫早期使用较多的方法,是搜索算法的一种。 2、dfs的目的是要达到被搜索结构的叶结点,即那些不包含任何超链的HTML文件。 3、dfs根据已有的邻

Twinkle_sone的博客 1万+

【2】深度优先算法详解

深度优先算法(Depth-First Search,DFS)与广度优先算法(BFS)已经有很多介绍了,深度优先算法(DFS)是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问过为止。

weixin_41026617的博客 1784
上一篇: 使用scikit-learn实现决策树的算法模板
下一篇: Python基础中的一些重点
林下的码路
博客等级 码龄12年 295粉丝 506原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林下的码路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值