bfs求解倒水問題

2021-10-03 09:17:57 字數 3514 閱讀 2486

倒水問題

fill a表示倒滿a杯empty a表示倒空a杯,pour a b表示把a的水倒到b杯並且把b杯倒滿或a倒空。

input

輸入包含多組資料。每組資料輸入 a, b, c

資料範圍 0 < a <= b 、c <= b <=1000 、a和b互質。

output

你的程式的輸出將由一系列的指令組成。這些輸出行將導致任何乙個罐子正好包含c單位的水。每組資料的最後一行輸出應該是「success」。輸出行從第1列開始,不應該有空行或任何尾隨空格。

sample input

2 7 5

2 7 4

sample output

fill b

pour b a

success

fill a

pour a b

fill a

pour a b

success

notes

如果你的輸出與sample output不同,那沒關係。對於某個"a b c"本題的答案是多解的,不能通過標準的文字對比來判定你程式的正確與否。

所以本題由 spj(special judge)程式來判定你寫的**是否正確。

通過結構體儲存a,b杯的狀態以及導致此狀態的動作。

改變a,b杯的狀態共有六種動作: 編號

操作對a的影響

對b的影響

0fill a

a=amax

b=b1

empty a

a=0b=b

2fill b

a=ab=bmax

3empty b

a=ab=0

4pour a b

若 a < bmax - b , a=0; 否則,a =a-(bmax-b)

若 a < bmax - b ,b=a+b ;否則,b=bmax

5pour b a

若 b < amax - a , a=a+b; 否則,a =amax

若 b < amax - a , b=0; 否則,b =b-(amax-a)

使用佇列儲存狀態,使用map儲存導致當前狀態的前乙個狀態,從佇列中彈出狀態x後,對x進行上述六種操作,得到狀態y,判斷y是否在map中存在,如果不存在,將y壓入佇列,並且向map中插入狀態x,y當狀態xa或者b等於c的時候,迴圈結束。利用map尋找當前狀態的前一狀態,使用遞迴的方式輸出,利用靜態陣列儲存對應編號的操作,也可以使用map對映編號和相應操作。

這個題真的是調了很久(菜是原罪),踩到的坑主要有:

向佇列中壓入結構體變數時,我開始時使用的是demo.a = a; demo.b = temp.b; demo.order = 0; q.push(demo);,但是vs在這裡報錯stack overflow,我去設定了堆疊的容積沒有解決,我又過載了複製建構函式state(const state& p)(雖然我覺得沒有必要), 甚至我還過載了建構函式,建立臨時變數插入q.push(state(demo.a, demo.b, 4));, 這樣不報錯了,然鵝,提交oj之後還是顯示re。

很久之後我發現確實爆棧了,因為我有兩個地方處理不恰當,乙個是執行操作fill a的時候沒有判斷a是否是滿的,這樣就導致倒空倒滿這些動作有大量重複。另乙個是我在判斷是否map中存在這種狀態之前,就把這種狀態壓入佇列中,這也會導致佇列中有很多重複狀態。

受上學期資料結構的影響,我堅持自己寫佇列,寫棧,後果就是我每個**都寫了幾百行廢話,一定要去用啊啊啊

注意變數初始化問題,要在建構函式中初始化,另外,vs實在太強大了,我忘了寫竟然編譯通過了,雖然dev很難受,但至少他誠實(捂臉

好吧,我覺得這個反思真的狗話連篇,**虐我千百遍,我待**如初戀,如果**有情感,它一定覺得我是個憨憨,遇到問題別想得複雜,99%都是因為粗心啦!

#include

#include

#include

#include

#include

using

namespace std;

struct state

bool

operator

<

(const state& p)

const

state()

state

(int aa,

int bb)

// state(const state& p)

//

state

(int aa,

int bb,

int oo)};

string orders[6]

=; map front;

void

output

(state conse)

void

bfs_pour

(int a,

int b,

int c)

//fill a

if(temp.a!=a)

//先判斷再決定,否則這個分支就是重複的

}//empty a

if(temp.a!=0)

}//fill b

if(temp.b!=b)

}//empty b

if(temp.b!=0)

}//pour a b

if(temp.a >=

(b - temp.b)

)//把b倒滿

else

//把a倒空

if(front.

find

(state

(demo.a, demo.b,4)

)== front.

end())

//pour b a

if(temp.b >=

(a - temp.a)

)//把a倒滿

else

//把b倒空

if(front.

find

(state

(demo.a, demo.b,5)

)== front.

end())

}return;}

intmain()

front.

clear()

;bfs_pour

(asize,bsize, csize);}

return0;

}

倒水問題 bfs

題目 倒水問題 fill a 表示倒滿a杯,empty a 表示倒空a杯,pour a b 表示把a的水倒到b杯並且把b杯倒滿或a倒空。輸入 輸入包含多組資料。每組資料輸入 a,b,c,資料範圍 0 a b c b 1000 a和b互質。輸出 你的程式的輸出將由一系列的指令組成。這些輸出行將導致任何...

倒水問題BFS

傳送門.題意兩個杯子容量為a,b,有6個操作 fill 1 裝滿a fill 2 裝滿b drop 1 倒掉a drop 2 倒掉b pour 1,2 a倒給b,到b滿為止 pour 2,1 b倒給a,到a滿為止 問最少多少次能有其中乙個杯子裡面有c公升水。輸出相應操作。bfs搜尋6種情況,煩是真的...

poj 3414 倒水問題 bfs

思路 就是bfs,有六種操作,fill 1或2,drop 1或2 將1倒到2,將2倒到1。要注意的是要使用標記陣列vis i j 表示左邊的杯子為i公升,右邊的杯子為j公升,如果已被標記說明之前已經出現這種情況,就不要入隊。從 0,0 開始bfs。因為題目中需要輸出如何倒,那麼就需要儲存路徑。以前似...