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

相关文章

java如何解压zip压缩包

《java如何解压zip压缩包》:本文主要介绍java如何解压zip压缩包问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解压zip压缩包实例代码结果如下总结java解压zip压缩包坐在旁边的小伙伴问我怎么用 java 将服务器上的压缩文件解压出来,

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

java中新生代和老生代的关系说明

《java中新生代和老生代的关系说明》:本文主要介绍java中新生代和老生代的关系说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、内存区域划分新生代老年代二、对象生命周期与晋升流程三、新生代与老年代的协作机制1. 跨代引用处理2. 动态年龄判定3. 空间分

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一