題意:給你兩個杯子,分別容量爲A(1),B(2)和一個C,C是須要通過下列操做,獲得的一個升數。
(1) FILL(i) :把編號爲i的杯子中水灌滿
(2)DROP(i):把編號爲i的杯子中水所有倒了
(3)POUR(i,j):把編號爲i的杯子中的水倒入編號爲j的杯子中,若是編號j杯子中水滿了,編號i杯子水就不繼續倒了
問:能不能通過有限次(1)(2)(3)操做,獲得A,B中其中一個知足C升的水就能夠,能夠的話輸出最少次數並把操做輸出,不然輸出「impossble」node
思路:最少,容易想到bfs,加上倒水過程的模擬,也就6種狀況,模擬操做預處理以後,後面會變得很好寫,其中的過程,看代碼註釋吧。
補:咱們能夠把A,B中升數狀況給記錄下,出現過的<A,B>就不須要再次bfs了,否則應該會TLEios
1 #include <iostream> 2 #include <cstring> 3 #include<vector> 4 #include<string> 5 #include <cmath> 6 #include <map> 7 #include <queue> 8 #include <algorithm> 9 using namespace std; 10 11 #define inf (1LL << 31) - 1 12 #define rep(i,j,k) for(int i = (j); i <= (k); i++) 13 #define rep__(i,j,k) for(int i = (j); i < (k); i++) 14 #define per(i,j,k) for(int i = (j); i >= (k); i--) 15 #define per__(i,j,k) for(int i = (j); i > (k); i--) 16 17 int A_L, B_L, C_L; 18 19 //六種操做,都先預處理好 20 string op[6] = { "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", 21 "POUR(1,2)", "POUR(2,1)" }; 22 //其實算一個類用 23 struct node{ 24 25 int A,B; //A,B杯子中水升數狀況 26 vector<string > str; //記錄操做 27 // int l; 28 node(int a = 0, int b = 0){ A = a; B = b; } 29 30 void Fill(int num){ //(1)操做處理 31 if (num == 1) A = A_L; 32 else B = B_L; 33 } 34 35 void Drop(int num){ //(2)操做處理 36 if (num == 1) A = 0; 37 else B = 0; 38 } 39 40 void Pour(int num){ //(3)操做處理 41 if (num == 1){ 42 int tmp = A; 43 A -= (A >= B_L - B ? (B_L - B) : A); 44 B = (tmp >= B_L - B ? B_L : B + tmp); 45 } 46 else{ 47 int tmp = B; 48 B -= (B >= A_L - A ? (A_L - A) : B); 49 A = (tmp >= A_L - A ? A_L : A + tmp); 50 } 51 } 52 53 }; 54 55 void fun(string str){ 56 cout << str << endl; 57 } 58 59 void bfs(){ 60 61 map<pair<int, int>, bool> mp; //記錄<A,B>的狀況 62 63 node init; 64 /* 65 pair<int,int > p (init.A, init.B); 66 mp[p] = true; 67 */ 68 69 queue<node> que; 70 que.push(init); 71 72 while (!que.empty()){ 73 74 node key = que.front(); 75 que.pop(); 76 77 pair<int, int> o( key.A, key.B ); 78 if (mp[o]) continue; //判斷這個<A,B>有誤出現過,出現了就不繼續下去了 79 mp[o] = true; //沒出現過,標記一下 80 81 //六種狀況 82 rep(p, 1, 6){ 83 84 node tmp = key; 85 86 if (p == 1) tmp.Fill(1),tmp.str.push_back(op[0]); 87 else if (p == 2) tmp.Fill(2), tmp.str.push_back(op[1]); 88 else if (p == 3) tmp.Drop(1), tmp.str.push_back(op[2]); 89 else if (p == 4) tmp.Drop(2), tmp.str.push_back(op[3]); 90 else if (p == 5) tmp.Pour(1), tmp.str.push_back(op[4]); //pour(1,2) 91 else if (p == 6) tmp.Pour(2), tmp.str.push_back(op[5]); //pour(2,1) 92 93 //其中一個知足便可 94 if (tmp.A == C_L || tmp.B == C_L){ 95 cout << (int)tmp.str.size() << endl; 96 97 //遍歷tmp的vector 98 for_each(tmp.str.begin(), tmp.str.end(), fun); 99 100 return; 101 } 102 103 o = make_pair(tmp.A, tmp.B); //也是判斷下新的<A,B>是否出現過 104 if (!mp[o]) que.push(tmp); //出現過,再也不壓入隊列 105 } 106 } 107 108 //沒法得出C 109 cout << "impossible" << endl; 110 111 } 112 113 int main(){ 114 115 ios::sync_with_stdio(false); 116 cin.tie(0); 117 118 cin >> A_L >> B_L >> C_L; //記錄A的最大容量,B的最大容量,標準C 119 bfs(); 120 121 return 0; 122 }