java 水杯问题_三壶问题(水杯倒水问题)

2023-10-28 11:50
文章标签 java 问题 水杯 倒水 三壶

本文主要是介绍java 水杯问题_三壶问题(水杯倒水问题),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近有看到一道算法题,题虽简单,但网上给出的解释大都不太完善,甚至还有一言不合直接贴代码的,今天正好有时间,就写一下自己对这道问题的理解。题目如下:

320e8123aae9

Snipaste_2019-08-09_16-38-27.png

这类问题会给你两个或三个没有刻度的杯子,让你倒出指定容量的水。问法一般有两种:能不能倒出指定容量的水|最少倒几次能倒出指定容量的水

注意,这两种问法的处理方式是不同的。

能否倒出指定容量的水

这里问的是能否导出,所以我们不需要知道具体的步骤,只用弄懂该问题是否有解。

要倒出4品脱的水,也就是说8品脱壶要有4品脱水,剩下两个空壶共享4品脱水,这里就成了一个函数问题:5x + 3y = 4有没有整数解(包括正和负)。根据裴蜀定理(对于给定的正整数a,b,方程ax + by = c有解的充要条件为c是gcd(a,b)的整数倍),本题转化成了求解最大公约数问题,可以用欧几里得算法,连续整数检测算法,以及中学时代的算法(质因数)求解。

最少倒几次能倒出指定容量的水

毫无疑问,遇到这种求最少又不复杂的问题,可以考虑广度优先算法。

初始状态是[8,0,0],做一次倒水之后的情况有[3,5,0],[5,0,3]。照着这个思路一步步走下去,即可找出最优解。挂一张盗来的图:

320e8123aae9

Snipaste_2019-08-09_18-13-00.png

Lua实现如下:

local tBeginWater = {8, 0, 0}

local tCups = {8, 3, 5}

local nResultWater = 4

local tQueue = {tBeginWater} --lua没有队列容器,这里用table模拟

function CheckFinished()

for k,v in ipairs(tQueue[1]) do

if v == nResultWater then

return true

end

end

end

function CheckSameWater(tWater)

local tPreWater = tWater.tPreWater

local nSameValueCount

while tPreWater do

nSameValueCount = 0

for k,v in ipairs(tPreWater) do

if v ~= tWater[k] then

break

else

nSameValueCount = nSameValueCount + 1

end

end

if nSameValueCount == #tCups then

return true

else

tPreWater = tPreWater.tPreWater

end

end

return false

end

function PourWater(tCurWater) --bfs

for i=1,#tCups do

if tCurWater[i] > 0 then

for j=1, #tCups - 1 do

local nCupId = i+j > #tCups and i+j-#tCups or i+j

if tCups[nCupId] > tCurWater[nCupId] then

local nRemainCapacity = tCups[nCupId] - tCurWater[nCupId]

local nDumpWater = nRemainCapacity > tCurWater[i] and tCurWater[i] or nRemainCapacity

local tNextWater = clone(tCurWater)

tNextWater[i] = tNextWater[i] - nDumpWater

tNextWater[nCupId] = tNextWater[nCupId] + nDumpWater

tNextWater.tPreWater = tCurWater

if not CheckSameWater(tNextWater) then

table.insert(tQueue, tNextWater)

end

end

end

end

end

table.remove(tQueue, 1)

end

while not CheckFinished() do

local tCurWater = tQueue[1]

PourWater(tCurWater)

end

clone实现:

function clone(object)

local lookup_table = {}

local function _copy(object)

if type(object) ~= "table" then

return object

elseif lookup_table[object] then

return lookup_table[object]

end

local newObject = {}

lookup_table[object] = newObject

for key, value in pairs(object) do

newObject[_copy(key)] = _copy(value)

end

return setmetatable(newObject, getmetatable(object))

end

return _copy(object)

end

总结

可以先判断是否能倒出,再用广度优先求出最小次数

这篇关于java 水杯问题_三壶问题(水杯倒水问题)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/293024

相关文章

基于SpringBoot+Mybatis实现Mysql分表

《基于SpringBoot+Mybatis实现Mysql分表》这篇文章主要为大家详细介绍了基于SpringBoot+Mybatis实现Mysql分表的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录基本思路定义注解创建ThreadLocal创建拦截器业务处理基本思路1.根据创建时间字段按年进

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("