關於杯子量水的一種演算法

2021-07-26 11:06:45 字數 1481 閱讀 1502

題目:

有兩個水罐a,b,容量分別為x,y,均為不小於1的整數,在沒有任何刻度記號的下,可以量出那些數量單位的水

輸入示例

4 3輸出示例

1 2 3 4 5 6 7

輸入示例2

1 2輸出示例2

1 2 3

演算法:

以乙個5公升乙個6公升杯子倒3公升水為例,這兩個杯子根據裝的水量不同,共有22種狀態,而加水倒水的過程就是在這些狀態之間切換的過程,兩個杯子都是空的是初始狀態,其中有乙個杯子的水是3陞是最終狀態,所以這個問題可以用有限狀態機來解決。為了直觀起見,把這些狀態根據兩個杯子的水量分布在二維**中,於是乎得出了下面這個圖:

圖中:橫座標表示乙個杯子(a)的水量,縱座標表示另乙個杯子(b)的水量,灰色框表示不存在的狀態,黃色框表示初始狀態,藍色框表示最終狀態。

下面就是如何在這些狀態中進行切換了。首先,可以把某個杯子加滿水,在圖中則表示為從零狀態越過灰色區域跳到對面的滿狀態,把b杯子加滿就是從上下到,如圖2,把a杯子加滿就是從左到右,如圖3。

把某個杯子倒空,則方向相反,圖略。

將水從某個杯子倒進另乙個杯子則可以用從原狀態向左下或右上方向的45度線表示,目標狀態就表示倒入的量和原杯剩餘的量。如圖4表示將盛有4l水的a杯子中的水倒入b杯,倒完後b杯水有4l,a懷為空。圖5表示a杯滿,b杯1l,從a杯倒入b杯後,b杯滿,a杯剩2l。圖6表示a杯1l,b杯滿,將b杯倒入a杯後,a杯滿,b杯空。這些都是允許的狀態變化。變化的原則就是只能在左下倒右上的45度方向上,因為在這個方向上的變化,水總量是不變的。

現在,得出了幾種允許的變化,看能不能從初始狀態沿著這樣的線到達最終狀態。

一開始,就有兩種選擇,先試試向右吧。得到圖7。

接下來只有兩種選擇,向左下或者向下,向下就是都倒滿,接下來的操作只能再倒空乙個杯子,沒什麼意義,所以只有一種選擇,向左下,到(1,5),得到圖8。

接下來有兩種選擇,顯然,再回去以及向右都是沒有意義的,所以只有一種選擇,那就是向上到(1,0),得到圖9。

同樣的,向右的目的地已經走過了,那麼向左下,得圖10。

按這樣的思路,最終可以得到圖11。達到了最終狀態。

這裡得出的解就是:

1、a加滿(6,0)

2、a倒b(1,5)

3、b倒空(1,0)

4、a倒b(0,1)

5、a加滿(6,1)

6、a倒b(2,5)

7、b倒空(2,0)

8、a倒b(0,2)

9、a加滿(6,2)

10、a倒b(3,5)(得到3l)

如果一開始先向下也就是先加滿b,結果也是比較類似的。

如果到達某個狀態,找不到下一步,或者所有下一步都會回到以前曾經到達過的狀態,則無解。

在兩個杯子的情況下,除第一步外基本沒有可多選的分支。

如果在多個杯子的情況下,則用多維距陣來表示狀態,而可選分支也會隨維度增加而增加,形成搜尋樹,各位可以自己進一步進行探索。

一種濾波演算法

剛看到要寫濾波演算法的時候懵了,想著是不是要去掉最大值 最小值什麼的,感覺很高大上 於是開始查資料了解,發現濾波演算法其實有很多種方法,如下列舉了一些,當然能起到的濾波作用也是不同的 於是我看了下,選擇了一種最簡單實用的濾波演算法學習了一下,即下面的中位值濾波演算法 簡單來說就是多次取樣,排序,取中...

一種輕量的openresty路由設計

但出於安全性考慮,決定給訪問的介面位址加個白名單功能,不在白名單的位址不允許訪問。這裡載入了乙個對應目錄的route config.lua,由於這個config檔案內容較小,所以我把內容直接列了出來 白名單列表 local whitelist 路由重寫列表 local rewritelist ret...

關於封裝的一種解釋

封裝這個解釋,我一直喜歡用cpu作為例子 cpu把所有的電阻電容閘電路等都封裝起來,只留出一些管腳 介面 讓使用者使用,cpu能暴露什麼,不能暴露什麼,是生產商設計決定的,使用者不能直接操作cpu的電阻電容等等,但可以通過給管腳適當的電壓來控制電阻電容等,也就是說使用者不能直接訪問cpu的屬性,但是...