摘要:問題描述有三個容器分別是三升五升和八升的水桶,其中容積為八升的水桶裝滿了水,其余兩桶為空。水桶沒有刻度,除這三個桶外不能使用其它容器,將升水等分為兩份升的水。
此為《算法的樂趣》讀書筆記,我用javascript重新實現算法。
問題描述解題思路有三個容器分別是三升、五升和八升的水桶,其中容積為八升的水桶裝滿了水,其余兩桶為空。水桶沒有刻度,除這三個桶外不能使用其它容器,將8升水等分為兩份4升的水。
變量定義以三水桶盛水量為一個矢量狀態,倒水可以推動狀態的改變,這樣會形成一個狀態樹,我們采用深度優先搜索方式進行窮舉。
書中使用用了C++標準庫的雙端隊列,還用了結構體,并將桶狀態封裝成了類,比較難看懂,我發現用javascript進行合理的設計,代碼簡單易懂^_^。
桶的最大容量及狀態變化隊列
var FullBacket = [8,5,3] //桶的最大容量 var states = [[8,0,0]]; //狀態隊列,js的數組已經已經有隊列和堆棧的支持檢測倒水操作是否可行
限制條件為:桶的序號0~2;倒出水的桶不能為空;倒入水的桶不能是滿的。
function CanTakeDumpAction(curr,from,to){ if(from >= 0 && from < 3 && to >= 0 && to < 3){ if(from != to && curr[from] > 0 && curr[to] < FullBacket[to]){ return true; } } return false; }倒水操作
倒水量的計算要注意兩個方面,一是目標桶的剩余容積;二是源桶的剩余水量,兩者取小。
function DumpWater(curr,from,to){ var next = curr.slice(); //js對象為引用傳值,這里要復制一份 var dump_water = FullBacket[to] - curr[to] > curr[from] ? curr[from] : FullBacket[to] - curr[to] //倒水量的計算 next[from] -= dump_water; next[to] += dump_water; return next; }檢測新狀態是否已經出現過
這個函數是保證不會進入死循環,注意:foreach中途不能退出,此處不能用它。
function IsStateExist(state){ for(var i = 0; i < states.length; i++){ if(state[0] == states[i][0] && state[1] == states[i][1] && state[2] == states[i][2]){ return true; } } return false; }狀態搜索主函數
邊界條件有兩個,一為找到了正確解,一為所有狀態都檢測完,并未找到正確解。
(function SearchState(states){ var curr = states[states.length - 1]; if(curr[0] == 4 && curr[1] == 4){ //找到正確解 var rs = "" states.forEach(function(al){ rs += al.join(",") + " -> "; }); console.log(rs.substr(0,rs.length - 4)) } for(var j = 0; j < 3; j++){ //所有的倒水方案即為桶編號的全排列 for(var i = 0; i < 3; i++){ if(CanTakeDumpAction(curr,i,j)){ var next = DumpWater(curr,i,j); if(!IsStateExist(next)){ //找到新狀態 states.push(next); SearchState(states); states.pop(); } } } } })(states);16組正確解
8,0,0 -> 3,5,0 -> 0,5,3 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 4,4,0 8,0,0 -> 3,5,0 -> 3,2,3 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 4,4,0 8,0,0 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 0,5,3 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 4,4,0 8,0,0 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 4,4,0 8,0,0 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 4,4,0 8,0,0 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 0,5,3 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 4,4,0 8,0,0 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 4,4,0 8,0,0 -> 3,5,0 -> 3,2,3 -> 0,5,3 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 4,4,0 8,0,0 -> 5,0,3 -> 0,5,3 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 4,4,0 8,0,0 -> 5,0,3 -> 5,3,0 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 4,4,0 8,0,0 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 0,5,3 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 4,4,0 8,0,0 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 4,4,0 8,0,0 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 0,5,3 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 4,4,0 8,0,0 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 7,0,1 -> 7,1,0 -> 4,1,3 -> 4,4,0 8,0,0 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 4,4,0 8,0,0 -> 5,0,3 -> 5,3,0 -> 2,3,3 -> 2,5,1 -> 0,5,3 -> 3,5,0 -> 3,2,3 -> 6,2,0 -> 6,0,2 -> 1,5,2 -> 1,4,3 -> 4,4,0
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79162.html
摘要:三個水桶都沒有刻度,現在需要將大水桶中的升水等分成兩份,每份都是升水,附加條件是只能這三個水桶,不能借助其他輔助容器。假設將每個狀態下三個水桶中的水的體積作為。 智力題目 有三個容積分別為3升、5升、8升的水桶,其中容積為8升的水桶中裝滿了水,容積為3升和容積為5升的水桶都是空的。三個水桶都沒有刻度,現在需要將大水桶中的8升水等分成兩份,每份都是4升水,附加條件是只能這三個水桶,不能借...
摘要:之所以把計數排序桶排序基數排序放在一起比較,是因為它們的平均時間復雜度都為。動畫計數排序思想找出待排序的數組中最大和最小的元素。桶排序計數排序能派上用場嗎手機號碼有位,范圍太大,顯然不適合用這兩種排序算法。 showImg(https://segmentfault.com/img/bVbuF9e?w=900&h=500); 1. 前言 算法為王。 想學好前端,先練好內功,只有內功深厚者...
摘要:筆者寫的數據結構與算法之美系列用的語言是,旨在入門數據結構與算法和方便以后復習。這應該是目前較為簡單的十大經典排序算法的文章講解了吧。比如原本在的前面,而,排序之后,在的后面十大經典排序算法冒泡排序思想冒泡排序只會操作相鄰的兩個數據。 showImg(https://segmentfault.com/img/bVbvHet); 1. 前言 算法為王。想學好前端,先練好內功,內功不行,就...
閱讀 1294·2021-10-08 10:05
閱讀 4107·2021-09-22 15:54
閱讀 3105·2021-08-27 16:18
閱讀 3107·2019-08-30 15:55
閱讀 1436·2019-08-29 12:54
閱讀 2748·2019-08-26 11:42
閱讀 543·2019-08-26 11:39
閱讀 2129·2019-08-26 10:11