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”。

思路:bfs,把六种情况都模拟枚举(代码写的比较形象),需要标记出现过的三个容器的容量情况,否则会TLE。


  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 }



猜你喜欢

转载自www.cnblogs.com/SSummerZzz/p/11164276.html