臥槽!被struct折服了!以後就用它了!
題目概述:
這道題就是經典的倒水問題,不禁感慨一句以前需要人腦來做的東西現在直接計算機模擬就夠了。
給定三個數字,前兩個數字表示的是兩個桶的最大容量,第三個數字表達的是目標容量。一共有三種操作,分別是清空某桶,裝滿某桶,還有把一個桶裏面的水倒入另一個桶(如果會溢出就只能剛好倒滿,剩下的水留在自己的桶裏)。要求輸出最少的操作步數,並且要輸出操作方法。
算法思想:
因爲題目要求輸出的是最少操作步數,就想到了用BFS來枚舉各個狀態,而且其實可枚舉出來的狀態真的很少呀。
然後vis[][]這個數組記錄的是(i,j)這個水流組合現在有沒有出現過,這個其實不止起了優化的作用,而是保證程序可以終止,因爲假如輸入的數據是一個無法達到的數據的話,這個程序就會無限期枚舉下去,所以這個數組就是必要的。
知道了這些之後,仍然要解決路徑的問題,那麼解決方法就是開了一個struct,比我那個pair<int,int>不知高到哪裏去,因爲這個結構體可以存儲string,然後用string連接的操作就可以把所有操作記錄下來,實乃高招。哦也許讀者認爲很容易就想到但是我比較弱啊對不起 Orz。
希望代碼分層明顯的讀者可以自然寫幾個子函數,但是我當時覺得沒什麼必要就沒寫了。
代碼部分:
#include <iostream> #include <queue> #include <map> #include <string> using namespace std; int a, b, c; int vis[117][117] = { 0 }; struct node{ int a_m, b_m; string step; node(int a_v, int b_v, string s_v) : a_m(a_v), b_m(b_v), step(s_v) {} }; int main() { int a, b, c; bool flag = false; cin >> a >> b >> c; queue<node> q; node start(0, 0, ""); node result(0, 0, ""); q.push(start); vis[0][0] = 1; while (!q.empty()) { if (flag) break; node next = q.front(); q.pop(); if (next.a_m == c || next.b_m == c){ flag = true; result = next; } if (next.a_m != 0) { node tmp = node(0, next.b_m, next.step + '1'); if (!vis[tmp.a_m][tmp.b_m]) { q.push(tmp); // We don't need to check whether this satisfy results vis[tmp.a_m][tmp.b_m] = 1; } } if (next.b_m != 0) { node tmp = node(next.a_m, 0, next.step + '2'); if (!vis[tmp.a_m][tmp.b_m]) { q.push(tmp); vis[tmp.a_m][tmp.b_m] = 1; } } if (next.a_m != a) { node tmp = node(a, next.b_m, next.step + '3'); if (!vis[tmp.a_m][tmp.b_m]) { q.push(tmp); vis[tmp.a_m][tmp.b_m] = 1; } } if (next.b_m != b) { node tmp = node(next.a_m, b, next.step + '4'); if (!vis[tmp.a_m][tmp.b_m]) { q.push(tmp); vis[tmp.a_m][tmp.b_m] = 1; } } if (next.a_m != 0 && next.a_m+next.b_m <= b && next.b_m != b){ node tmp = node(0, next.a_m + next.b_m, next.step + '5'); if (!vis[tmp.a_m][tmp.b_m]) { q.push(tmp); vis[tmp.a_m][tmp.b_m] = 1; } } if (next.a_m !=0 && next.a_m+next.b_m > b && next.b_m != b){ node tmp = node(next.a_m+next.b_m-b, b, next.step + '5'); if (!vis[tmp.a_m][tmp.b_m]) { q.push(tmp); vis[tmp.a_m][tmp.b_m] = 1; } } if (next.b_m !=0 && next.a_m+next.b_m <= a && next.a_m != a){ node tmp = node(next.a_m + next.b_m, 0, next.step + '6'); if (!vis[tmp.a_m][tmp.b_m]) { q.push(tmp); vis[tmp.a_m][tmp.b_m] = 1; } } if (next.b_m != 0 && next.a_m + next.b_m>a && next.a_m != a){ node tmp = node(a, next.a_m+next.b_m-a, next.step + '6'); if (!vis[tmp.a_m][tmp.b_m]) { q.push(tmp); vis[tmp.a_m][tmp.b_m] = 1; } } } if (!flag) cout << "impossible" << endl; else { cout << result.step.size() << endl; for (int i = 0; i < result.step.size(); i++){ switch (result.step[i]) { case '1': cout << "DROP(1)" << endl; break; case '2': cout << "DROP(2)" << endl; break; case '3': cout << "FILL(1)" << endl; break; case '4': cout << "FILL(2)" << endl; break; case '5': cout << "POUR(1,2)" << endl; break; case '6': cout << "POUR(2,1)" << endl; break; } } } return 0; }