uva oj 10603 解题报告

 

 

广度优先算法 || 需要优化 


1 . 题目描述

There are three jugs with a volume of a, b and c liters. (a, b, and c are positive integers not greater than 200). The first and the second jug are initially empty, while the third

is completely filled with water. It is allowed to pour water from one jug into another until either the first one is empty or the second one is full. This operation can be performed zero, one or more times.

 

You are to write a program that computes the least total amount of water that needs to be poured; so that at least one of the jugs contains exactly d liters of water (d is a positive integer not greater than 200). If it is not possible to measure d liters this way your program should find a smaller amount of water d' < d which is closest to d and for which d' liters could be produced. When d' is found, your program should compute the least total amount of poured water needed to produce d' liters in at least one of the jugs.

Input

The first line of input contains the number of test cases. In the next T lines, T test cases follow. Each test case is given in one line of input containing four space separated integers - a, b, c and d.

Output

The output consists of two integers separated by a single space. The first integer equals the least total amount (the sum of all waters you pour from one jug to another) of poured water. The second integer equals d, if d liters of water could be produced by such transformations, or equals the closest smaller value d' that your program has found.

 

Sample Input

Sample Output

2

2 3 4 2

96 97 199 62

2 2

9859 62

 


2 .测试用例


Input 
5
12 23 42 14
12 53 75 23
56 23 34 2
23 55 72 25
124 86 173 84

output 
166 14 
728 23 
0 0 
23 23 
850 77


3 .  算法描述

     1. 主体思路:

               这道题主要是使用了 广度优先的算法(利用队列实现)。给定一个节点(一个三个杯子容量的状态),出队列,计算该节点符合题目要求的孩子节点(符合要求:1.按照倒水原则,将目标倒满或者将源倒空两种情况 2.该节点从来没有入过队列中)(调用“addSpringNode()”方法),之后将孩子节点入队列。
               由于题目要求如果找不到节点则输出最接近“des”的节点,所以 整个队列有两个状态(1.找到了des 2.目前还没有发现des)。初始状态是没有找到des("foundDes = false"),如果发现当前出队列的节点中有des,则立即改变状态(“foundDes = true”),这个状态的改变是不可逆的。
               根据题目要求,在没有找到des的状态时,需要找到一个最接近des的节点。那么在未找到状态时,程序需要维护一个最接近des的变量值(closestDes)&&一个该变量值对应的最小的倒出水的容量(closestAmount),在出队列时,对比当前节点与这两个变量,并根据规则修改两个变量。特别注意:如果程序达到了另外找到des的状态,那么这些变量就不需要再维护了

    2. 算法需要注意的细节

                a. 两种状态下,对于出队列元素的处理是不同的。状态1(未找到des):需要维护closestDes和closestAmount这两个变量,每个出队列的元素都需要比对。状态2(找到des):上面提到的两个变量可以放弃了,在这里需要维护一个新的变量,用来记录找到des时,最小的倒水容量(minAmount)。在这里需要特别注意,为了节省时间,并且 为解答树剪枝,只有当前节点已经消耗的倒水容量(amount)小于最小倒水容量(minAmount)时,才将该节点的孩子节点入队列(因为我们要找的是最小amount值的节点,当前节点的amount值已经大于了minAmount,已经没有必要再入队列了,孩子节点的amount值必然会大于minAmount)。
                

4 .程序中遇到的问题

    1. hashCode(): 要特别注意, 在覆盖了hashCode()方法后,一定要对equals()方法进行重写,保证当a.equals(b) ==true时候,a.hashCode()==b.hashCode。(这道题中有一个bug就是因为equals方法的问题,将重复的节点(有相同stats,虽然有不同的amount,但是在题目要求杯子中的容量相同时,状态就是相同的)写入了队列,造成了循环)。java中objece类默认是比较两个class的地址,如果地址相同
    2. newStats[] : 要特别注意变量的范围,在这道题中就是newStats[]被多次修改,以后要避免这个问题
    
    

5. 需要改进的地方

    1. 到底什么时候用全局变量,这个问题需要查些资料(可以用全局变量的标准是什么?)。
    2. 有机会的话看下别人的算法

6. 代码

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值