kuangbin專題 專題一 簡單搜索 Pots POJ - 3414

 

題目連接:https://vjudge.net/problem/POJ-3414

題意:給你兩個杯子,分別容量爲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 }
相關文章
相關標籤/搜索