摘要:問題描述有三個(gè)容器分別是三升五升和八升的水桶,其中容積為八升的水桶裝滿了水,其余兩桶為空。水桶沒有刻度,除這三個(gè)桶外不能使用其它容器,將升水等分為兩份升的水。
此為《算法的樂趣》讀書筆記,我用javascript重新實(shí)現(xiàn)算法。
問題描述解題思路有三個(gè)容器分別是三升、五升和八升的水桶,其中容積為八升的水桶裝滿了水,其余兩桶為空。水桶沒有刻度,除這三個(gè)桶外不能使用其它容器,將8升水等分為兩份4升的水。
變量定義以三水桶盛水量為一個(gè)矢量狀態(tài),倒水可以推動狀態(tài)的改變,這樣會形成一個(gè)狀態(tài)樹,我們采用深度優(yōu)先搜索方式進(jìn)行窮舉。
書中使用用了C++標(biāo)準(zhǔn)庫的雙端隊(duì)列,還用了結(jié)構(gòu)體,并將桶狀態(tài)封裝成了類,比較難看懂,我發(fā)現(xiàn)用javascript進(jìn)行合理的設(shè)計(jì),代碼簡單易懂^_^。
桶的最大容量及狀態(tài)變化隊(duì)列
var FullBacket = [8,5,3] //桶的最大容量 var states = [[8,0,0]]; //狀態(tài)隊(duì)列,js的數(shù)組已經(jīng)已經(jīng)有隊(duì)列和堆棧的支持檢測倒水操作是否可行
限制條件為:桶的序號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; }倒水操作
倒水量的計(jì)算要注意兩個(gè)方面,一是目標(biāo)桶的剩余容積;二是源桶的剩余水量,兩者取小。
function DumpWater(curr,from,to){ var next = curr.slice(); //js對象為引用傳值,這里要復(fù)制一份 var dump_water = FullBacket[to] - curr[to] > curr[from] ? curr[from] : FullBacket[to] - curr[to] //倒水量的計(jì)算 next[from] -= dump_water; next[to] += dump_water; return next; }檢測新狀態(tài)是否已經(jīng)出現(xiàn)過
這個(gè)函數(shù)是保證不會進(jìn)入死循環(huán),注意: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; }狀態(tài)搜索主函數(shù)
邊界條件有兩個(gè),一為找到了正確解,一為所有狀態(tài)都檢測完,并未找到正確解。
(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)){ //找到新狀態(tài) 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
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79162.html
摘要:三個(gè)水桶都沒有刻度,現(xiàn)在需要將大水桶中的升水等分成兩份,每份都是升水,附加條件是只能這三個(gè)水桶,不能借助其他輔助容器。假設(shè)將每個(gè)狀態(tài)下三個(gè)水桶中的水的體積作為。 智力題目 有三個(gè)容積分別為3升、5升、8升的水桶,其中容積為8升的水桶中裝滿了水,容積為3升和容積為5升的水桶都是空的。三個(gè)水桶都沒有刻度,現(xiàn)在需要將大水桶中的8升水等分成兩份,每份都是4升水,附加條件是只能這三個(gè)水桶,不能借...
摘要:之所以把計(jì)數(shù)排序桶排序基數(shù)排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。動畫計(jì)數(shù)排序思想找出待排序的數(shù)組中最大和最小的元素。桶排序計(jì)數(shù)排序能派上用場嗎手機(jī)號碼有位,范圍太大,顯然不適合用這兩種排序算法。 showImg(https://segmentfault.com/img/bVbuF9e?w=900&h=500); 1. 前言 算法為王。 想學(xué)好前端,先練好內(nèi)功,只有內(nèi)功深厚者...
摘要:筆者寫的數(shù)據(jù)結(jié)構(gòu)與算法之美系列用的語言是,旨在入門數(shù)據(jù)結(jié)構(gòu)與算法和方便以后復(fù)習(xí)。這應(yīng)該是目前較為簡單的十大經(jīng)典排序算法的文章講解了吧。比如原本在的前面,而,排序之后,在的后面十大經(jīng)典排序算法冒泡排序思想冒泡排序只會操作相鄰的兩個(gè)數(shù)據(jù)。 showImg(https://segmentfault.com/img/bVbvHet); 1. 前言 算法為王。想學(xué)好前端,先練好內(nèi)功,內(nèi)功不行,就...
閱讀 1310·2021-10-08 10:05
閱讀 4133·2021-09-22 15:54
閱讀 3114·2021-08-27 16:18
閱讀 3113·2019-08-30 15:55
閱讀 1448·2019-08-29 12:54
閱讀 2757·2019-08-26 11:42
閱讀 555·2019-08-26 11:39
閱讀 2139·2019-08-26 10:11