倒水問題
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
當狀態x
的a
或者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。因為題目中需要輸出如何倒,那麼就需要儲存路徑。以前似...