用Scala倒水

时间:2012-05-13 21:18:19

标签: algorithm scala recursion breadth-first-search

我正在尝试使用scala解决来自codechef的倾盆水问题。问题陈述如下:

  

鉴于两艘船,其中一艘可以容纳一升水和   另一个可以容纳b升水,确定   在其中一个中获得准确的c升水所需的步骤数   船只。

     

一开始两艘船都是空的。以下操作是   算作'步骤':

emptying a vessel,
filling a vessel,
pouring water from one vessel to the other, without spilling, until one of the vessels is either full or empty. 
     

输入

     

整数t,1< = t< = 100,表示测试用例的数量,接下来   由t组输入数据组成,每组由三个正整数组成   (第一个容器可以容纳的升数),b(数量为   第二个容器可以容纳的升,和c(最终的容量)   一个容器应含有的水(),不大于40000,   分开给出。

     

输出

     

对于每组输入数据,输出最小步数   需要获得c升,如果不可能则为-1。

     

示例示例输入:

     

2   五   2   3   2   3   4

     

示例输出:

     

2   -1

我正在接近这个问题作为图论问题。鉴于容器的初始配置为(0, 0),我通过应用操作获得容器的下一个状态:

递归地

FillAFillBPourAtoBPourBtoAEmptyAEmptyB,直到达到目标为止。

我的代码如下:

import scala.collection.mutable.Queue

def pour(initA:Int, initB:Int, targetCapacity:Int) {
    var pourCombinations = new scala.collection.mutable.HashMap[(Int, Int),Int]
    val capacityA = initA
    val capacityB = initB

    val processingQueue = new Queue[(Int, Int, Int, Int)]

    def FillA(a:Int, b:Int) = {
      (capacityA, b)                    
    }
    def FillB(b:Int, a:Int) = {
      (a, capacityB)
    }   
    def PourAtoB(a:Int, b:Int): (Int, Int) = {
      if((a == 0) || (b == capacityB)) (a, b) 
      else PourAtoB(a - 1, b + 1) 
    }
    def PourBtoA(b:Int, a:Int): (Int, Int) = { 
      if((b == 0) || (a == capacityA)) (a, b) 
      else PourBtoA(b - 1, a + 1)
    }
    def EmptyA(a:Int, b:Int) = {
      (0, b)
    }
    def EmptyB(a:Int, b:Int) = {
      (a, 0)
    }

    processingQueue.enqueue((0, 0, targetCapacity, 0))
    pourCombinations((0, 0)) = 0


    def pourwater(a:Int, b:Int, c:Int, numSteps:Int): Int = {
        println(a + ":" + b + ":" + c + ":" + numSteps)

        if((a == c) || (b == c)) {return numSteps}

        if(processingQueue.isEmpty && (pourCombinations((a,b)) == 1)) {return -1}

        //Put all the vals in a List of tuples
        val pStateList = scala.List(FillA(a, b), FillB(a, b), PourAtoB(a, b), PourBtoA(b, a), EmptyA(a, b), EmptyB(a, b))       

        pStateList.foreach{e =>
          {
            if(!pourCombinations.contains(e)) {
              pourCombinations(e) = 0
              processingQueue.enqueue((e._1, e._2, c, numSteps + 1))
            }
          }
        }   
        pourCombinations((a, b)) = 1
        val processingTuple = processingQueue.dequeue()
        pourwater(processingTuple._1, processingTuple._2, processingTuple._3, processingTuple._4)

     }
     val intialvalue = processingQueue.dequeue()
     pourwater(intialvalue._1, intialvalue._2, intialvalue._3, intialvalue._4)
}

这有几个问题,首先我不确定我的基本情况是否正确设置了递归步骤。此外,可能是因为我没有使用正确的Scala约定来解决此问题。另外,我希望pour函数在完成执行后返回numSteps。目前还没有这样做。

如果有人可以查看我的代码并用我的方法指出错误,那将是很棒的。

由于

0 个答案:

没有答案