2016.3.31 蘑菇街笔试编程题2

有4个瓶子,其容积分别为 10 ,6,5,4

初始状态为 10,0,0,0

现给出一个目标状态obj,问最少经过几部可以到达目标状态。

(注:每次倒水只能将自己倒空或将别杯倒满!)

############################################ 4个瓶子倒水问题BFS 2016.4.4
# 由一个状态list s可以到达的下一个状态的集合
def changeto(s,vvv):
    res = []
    for i in range(4):
        for j in range(4):
            if i==j or s[i]==0: # 自己不会向自己倒水,自己为0的时候也无法给别人倒水
                continue
            tmp = list(s)
            if s[i]+s[j]<vvv[j]: # j装的下时,全部给j
                tmp[i] = 0
                tmp[j] = s[i]+s[j]
            else: # j装不下时,把j装满,自己留剩下的
                tmp[i] = s[i]+s[j]-vvv[j]
                tmp[j] = vvv[j]
            res.append(tmp)
##    print "res:",res
    return res

## 进行BFS搜索,使用辅助数据结构队列q        
def bfs( obj ):
    vvv = [10,6,5,4] # 4个杯子中水的容量
    start = [10,0,0,0] # 起始状态
    q = [start] # 初始队列q
    rounds = 0 # 倒水的次数
    table = set([]) # 已经过的状态的集合

    while q:
        if obj in q: # 找到了obj状态,则成功!
            print rounds
            return
        
        rounds += 1 
        size = len(q)
        for i in range(size):
            curs = q.pop() # 当前状态curs
            if tuple(curs) in table: # 在集合中,则跳过
                continue
            table.add(tuple(curs)) # 否则加入集合
            q.extend( changeto(curs, vvv) )# 将fq状态的下一个状态集合加入q        
    print -1
    
while 1:
    try:
        obj = [int(x) for x in raw_input().split()]
    except:
        break
    bfs(obj)

如果无法到达目标状态,则标记为-1

运行结果如下:


你可能感兴趣的:(2016.3.31 蘑菇街笔试编程题2)