kuangbin專題 專題一 簡單搜索 很是可樂 HDU - 1495

 

題目連接:https://vjudge.net/problem/HDU-1495

題意:有兩個空杯(分別是N升和M升)和一罐滿的可樂S升,S = N + M,三個容器能夠互相傾倒,若是A倒入B,只有兩種狀況:
(1) A所有倒入B中,B中的升數小於等於B的最大容量。
(2)A部分倒入B中,B已經到達了B的最大容量。
問:有沒有可能把S升的可樂平分在任意兩個容器中,有的話得出最少操做次數,不然輸出「NO」。node

思路:bfs,把六種狀況都模擬枚舉(代碼寫的比較形象),須要標記出現過的三個容器的容量狀況,不然會TLE。ios


 

  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 NL, ML, SL, AVE;
 18 //bool vis[110][110][110];
 19 
 20 struct node{
 21 
 22     int N, M, S, V;
 23 
 24     node(int a, int b, int c, int d){
 25         N = a;
 26         M = b;
 27         S = c;
 28         V = d;
 29     }
 30     
 31     //這裏面內嵌的  if表示(1)狀況
 32     //             else表示(2)狀況
 33     void Pour(int f, int s){
 34 
 35         if (f == 1){
 36             if (s == 2){
 37                 int t = ML - M;
 38                 if (N >= t) N -= t, M = ML; //(1)
 39                 else M += N, N = 0; //(2)
 40             }
 41             else if (s == 3){
 42                 int t = SL - S;
 43                 if (N >= t) N -= t, S = SL;
 44                 else S += N, N = 0;
 45             }
 46         }
 47         else if (f == 2){
 48             if (s == 1){
 49                 int t = NL - N;
 50                 if (M >= t) M -= t, N = NL;
 51                 else N += M, M = 0;
 52             }
 53             else if (s == 3){
 54                 int t = SL - S;
 55                 if (M >= t) M -= t, S = SL;
 56                 else S += M, M = 0;
 57             }
 58         }
 59         else if (f == 3){
 60             if (s == 1){
 61                 int t = NL - N;
 62                 if (S >= t) S -= t, N = NL;
 63                 else N += S, M = 0;
 64             }
 65             else if (s == 2){
 66                 int t = ML - M;
 67                 if (S >= t) S -= t, M = ML;
 68                 else M += S, S = 0;
 69             }
 70         }
 71     }
 72 
 73 };
 74 
 75 //能夠看出,我用了兩個方法均可以標記狀況
 76 void bfs(){
 77 
 78     map<pair<int, int>, bool> mp;//標記三個容器的容量狀況,防止出下過的再次出如今隊列中
 79     pair<int, int > p(0, 0);
 80     mp[p] = true;
 81     node in(0, 0, SL, 0);
 82 //    vis[in.N][in.M][in.S] = true;
 83     queue<node> que;
 84     que.push(in);
 85 
 86     while (!que.empty()){
 87 
 88         node tmp = que.front();
 89         que.pop();
 90         
 91         //六種狀況,Pour(x,y) 把X中的倒入y中,應該是很清楚了
 92         rep(i, 1, 6){
 93             node t = tmp;
 94 
 95             if (i == 1) t.Pour(1, 2);
 96             else if (i == 2) t.Pour(1, 3);
 97             else if (i == 3) t.Pour(2, 1);
 98             else if (i == 4) t.Pour(2, 3);
 99             else if (i == 5) t.Pour(3, 1);
100             else if (i == 6) t.Pour(3, 2);
101             
102             //檢查有沒有出現平分了
103             int key = 0;
104             if (t.N == AVE) key++;
105             if (t.M == AVE) key++;
106             if (t.S == AVE) key++;
107             //平分了
108             if (key >= 2){
109                 cout << tmp.V + 1 << endl;
110                 return;
111             }
112 
113             p.first = t.N;
114             p.second = t.M;
115             pair<int, int > p(t.N, t.M);
116             if (!mp[p]/*!vis[t.N][t.M][t.S]*/){
117                 mp[p] = true;
118             //    vis[t.N][t.M][t.S] = true;
119                 que.push(node{ t.N, t.M, t.S, tmp.V + 1 });
120             }
121         }
122     }
123 
124     cout << "NO" << endl;
125 }
126 
127 int main(){
128 
129     ios::sync_with_stdio(false);
130     cin.tie(0);
131 
132     while (cin >> SL >> NL >> ML){
133 
134         memset(vis, 0, sizeof(vis));
135 
136         if (NL == 0 && ML == 0 && SL == 0) break;
137         AVE = SL / 2;
138         if (SL & 1){
139             cout << "NO" << endl;
140             continue;
141         }
142         bfs();
143     }
144 
145     return 0;
146 }
相關文章
相關標籤/搜索