B Pour Water(BFS解決倒水問題)

2021-10-03 12:20:47 字數 3308 閱讀 5640

倒水問題 「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)程式來判定你寫的**是否正確。

首先,應該由題意辨別出這個問題是隱式圖問題,可以使用bfs方法解決。

隱式圖問題:僅給出初始節點、目標節點、生成子節點的約束條件(由題意隱含給出)。

本題中初始節點為a、b杯中都為0(杯空),目標節點為a、b中任意一方水量為c,約束條件為a、b中水量不能超過自身容量等。

程式設計思路為:輸入並儲存——>bfs搜尋——>輸出進行的所有操作。

輸入並儲存很簡單,可用int型直接儲存。

bfs搜尋需要做抽象概念的轉變,我們每次操作有6種可能:把a倒入b(atob)、把b倒入a(btoa)、倒空a(emptya)、倒空b(emptyb)、倒滿a(filla)、倒滿b(fillb)。這六個動作類似於迷宮問題中乙個點的周圍四個點,它們分別通向6個相鄰狀態。

所以,我們利用佇列queue,每次都check這六種動作,看是否可以達成目標節點。

輸出進行的所有操作,模擬於輸出最短路徑,我們也需要宣告一些新變數,用於儲存有關操作順序的資料。

本次輸出資料用string類儲存,用vector陣列儲存所有要輸出的內容,這樣和用棧/佇列等資料結構儲存大同小異,選用順手的儲存即可。

至此,分析完成,按此思路編寫的**如下。(更詳細的解釋在注釋中體現)

#include

#include

#include

#include

#include

#include

using

namespace std;

struct status

//過載建構函式

status

(int xx,

int yy)

bool

operator

<

(const status &s)

const

else

}//過載操作符(大小比較方法)

bool

operator==(

const status &s)

const

//六個函式,分別代表了六種操作

status atob

(int b)

status btoa

(int a)

status filla

(int a)

status fillb

(int b)

status emptya()

status emptyb()

};vector ans;

//用於輸出操作,按序存放採用的操作

mapbool

> mp;

//儲存某狀態是否已經出現過

map from;

//儲存狀態的變化過程,前面由後面操作得來

queue q;

//佇列,用於bfs操作

void

check

(status x,status y,

int acnum)

case2:

case3:

case4:

case5:

case6:

} q.

push

(x);

//入佇列}}

//輸出操作函式

void

print

(status s)

for(

int i=ans.

size()

-2;i>=

0;i--

)printf

("success\n");

}void

bfs(

int a,

int b,

int a,

int b,

int c)

//成功,返回

check

(now.

atob

(b),now,1)

;check

(now.

btoa

(a),now,2)

;check

(now.

filla

(a),now,3)

;check

(now.

fillb

(b),now,4)

;check

(now.

emptya()

,now,5)

;check

(now.

emptyb()

,now,6)

;}}int

main()

//清空資料結構

bfs(0,

0,a,b,c);}

return0;

}

切記! 要輸出string類時,不能直接printf("%s",action),必須是action.c_str()。

map盡量不要直接在宣告時就賦初值,因為只有c++11及以後版本才支援這種操作。

提交時出現了tel問題,檢查後發現,錯在多次輸入時,沒有在一次輸出之後清空資料結構,導致後面資料結構中內容越來越多,遍歷時用時過多。

所以,不要忘記每次操作結束後呼叫clear()進行清空!

更換要輸出的內容,可能也會引起很大的改變,因為要更改很多資料結構或者宣告新的資料結構來儲存要輸出的資料,而不僅僅是更改cout那麼簡單。

解決 SVN解決衝突

intelij idea 使用svn,提交 前先更新 此時如果有衝突,就會提示你解決衝突。產生衝突的情況 a 和 b 兩名程式設計師,分別更新了同一版本 version 1 的 同時修改了乙個檔案。a提交 後,伺服器中的 是 version a 即 a 修改後的 b隨後提交 由於伺服器中的 已經不是...

svn is already locked解決方案

蛋疼的問題,不是一次遇到了,每次遇到的原因都不一樣,從網上摘錄了一些資料,整理成文,svn是個不錯的東東。svn already locked 解決辦法 在出錯資料夾下,滑鼠右鍵tortoisesvn clean up.svn錯誤 attempted to lock an already locke...

Bad for loop variable解決方法

錯誤為syntax error bad for loop variable 解決辦法 sudo dpkg reconfigure dash 在選擇項中選no 從 ubuntu 6.10 開始,ubuntu 就將先前預設的bash shell 更換成了dash shell 其表現為 bin sh 鏈結...