分红酒

题目描述

标题:分红酒
  有4个红酒瓶子,它们的容量分别是:9升, 7升, 4升, 2升
  开始的状态是 [9,0,0,0],也就是说:第一个瓶子满着,其它的都空着。
  允许把酒从一个瓶子倒入另一个瓶子,但只能把一个瓶子倒满或把一个瓶子倒空,不能有中间状态。

  这样的一次倒酒动作称为1次操作。

  假设瓶子的容量和初始状态不变,对于给定的目标状态,至少需要多少次操作才能实现?

  本题就是要求你编程实现最小操作次数的计算。
  输入:最终状态(逗号分隔)
  输出:最小操作次数(如无法实现,则输出-1)

例如:
输入:
9,0,0,0
应该输出:
0
输入:
6,0,0,3
应该输出:
-1
输入:
7,2,0,0
应该输出:
2

对于编程题目,要求选手给出的解答完全符合ANSI C++标准,不能使用诸如绘图、Win32API、中断调用、硬件操作或与操作系统相关的API。
代码中允许使用STL类库,但不能使用MFC或ATL等非ANSI c++标准的类库。例如,不能使用CString类型(属于MFC类库)。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意选择自己使用的编译环境。

分析

  1 #include <stdio.h>
  2 #include <math.h>
  3 #include <string.h>
  4 #define MAX 1500
  5 
  6 struct ST                       //定义一个结构体,记录某个状态的各个酒杯的值
  7 {
  8     int a, b, c, d;
  9 }qu[MAX];
 10 
 11 int visit[10][8][5];            //用于保存某个状态是否出现
 12 int step[10][8][5][3];          //用于记录达到某个状态的最短路径
 13 int front = -1, tail = 0;       //
 14 int A = 9, B = 7, C = 4, D = 2; //各个酒杯的最大值
 15 int ea, eb, ec, ed;             //输入的最终状态
 16 
 17 int min(int x, int y, int z)    //返回一个杯子能够向另一个杯子倒酒的量
 18 {
 19     if(x < z - y)
 20         return x;
 21     return z - y;
 22 }
 23 
 24 int EnterJudge(int x, int y, int z, int w) //判断某个状态是否出现,若出现则入队列
 25 {
 26     if(visit[x][y][z] == 0)
 27     {
 28         ++tail;
 29         qu[tail].a = x;
 30         qu[tail].b = y;
 31         qu[tail].c = z;
 32         qu[tail].d = w;
 33         visit[x][y][z] = 1;
 34         return 1;
 35     }
 36     return 0;
 37 }
 38 
 39 int bfs()                             //广度优先搜索
 40 {
 41     qu[0].a = 9;                      //初始状态入队列
 42     qu[0].b = 0;
 43     qu[0].c = 0;
 44     qu[0].d = 0;
 45 
 46     int temp, at, bt, ct, dt;
 47     while(front < tail)              //队列不空时循环
 48     {
 49         ++front;
 50         if(qu[front].a == ea && qu[front].b == eb
 51             &&qu[front].c == ec && qu[front].d == ed)
 52         {
 53             return step[ea][eb][ec][ed];    //找到要求的状态,返回最小次数
 54         }
 55         
 56 
 57         if(qu[front].a > 0 && qu[front].b < B) //a向b倒水
 58         {
 59             temp = min(qu[front].a, qu[front].b, B);
 60             at = qu[front].a - temp;
 61             bt = qu[front].b + temp;
 62             ct = qu[front].c;
 63             dt = qu[front].d;
 64             if(EnterJudge(at, bt, ct, dt))
 65                 step[at][bt][ct][dt] = 
 66                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
 67         }
 68         if(qu[front].a > 0 && qu[front].c < C) //a向c倒水
 69         {
 70             temp = min(qu[front].a, qu[front].c, C);
 71             at = qu[front].a - temp;
 72             bt = qu[front].b;
 73             ct = qu[front].c + temp;
 74             dt = qu[front].d;
 75             if(EnterJudge(at, bt, ct, dt))
 76                 step[at][bt][ct][dt] = 
 77                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
 78         }
 79         if(qu[front].a > 0 && qu[front].d < D) //a向d倒水
 80         {
 81             temp = min(qu[front].a, qu[front].d, D);
 82             at = qu[front].a - temp;
 83             bt = qu[front].b;
 84             ct = qu[front].c;
 85             dt = qu[front].d + temp;
 86             if(EnterJudge(at, bt, ct, dt))
 87                 step[at][bt][ct][dt] = 
 88                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
 89         }
 90 
 91         if(qu[front].b > 0 && qu[front].a < A) //b向a倒水
 92         {
 93             temp = min(qu[front].b, qu[front].a, A);
 94             at = qu[front].a + temp;
 95             bt = qu[front].b - temp;
 96             ct = qu[front].c;
 97             dt = qu[front].d;
 98             if(EnterJudge(at, bt, ct, dt))
 99                 step[at][bt][ct][dt] = 
100                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
101         }
102         if(qu[front].b > 0 && qu[front].c < C) //b向c倒水
103         {
104             temp = min(qu[front].b, qu[front].c, C);
105             at = qu[front].a;
106             bt = qu[front].b - temp;
107             ct = qu[front].c + temp;
108             dt = qu[front].d;
109             if(EnterJudge(at, bt, ct, dt))
110                 step[at][bt][ct][dt] = 
111                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
112         }
113         if(qu[front].b > 0 && qu[front].d < D) //b向d倒水
114         {
115             temp = min(qu[front].b, qu[front].d, D);
116             at = qu[front].a;
117             bt = qu[front].b - temp;
118             ct = qu[front].c;
119             dt = qu[front].d + temp;
120             if(EnterJudge(at, bt, ct, dt))
121                 step[at][bt][ct][dt] = 
122                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
123         }
124 
125         if(qu[front].c > 0 && qu[front].a < A) //c向a倒水
126         {
127             temp = min(qu[front].c, qu[front].a, A);
128             at = qu[front].a + temp;
129             bt = qu[front].b;
130             ct = qu[front].c - temp;
131             dt = qu[front].d;
132             if(EnterJudge(at, bt, ct, dt))
133                 step[at][bt][ct][dt] = 
134                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
135         }
136         if(qu[front].c > 0 && qu[front].b < B) //c向b倒水
137         {
138             temp = min(qu[front].c, qu[front].b, B);
139             at = qu[front].a;
140             bt = qu[front].b + temp;
141             ct = qu[front].c - temp;
142             dt = qu[front].d;
143             if(EnterJudge(at, bt, ct, dt))
144                 step[at][bt][ct][dt] = 
145                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
146         }
147         if(qu[front].c > 0 && qu[front].d < D) //c向d倒水
148         {
149             temp = min(qu[front].c, qu[front].d, D);
150             at = qu[front].a;
151             bt = qu[front].b;
152             ct = qu[front].c - temp;
153             dt = qu[front].d + temp;
154             if(EnterJudge(at, bt, ct, dt))
155                 step[at][bt][ct][dt] = 
156                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
157         }
158 
159         if(qu[front].d > 0 && qu[front].a < A) //d向a倒水
160         {
161             temp = min(qu[front].d, qu[front].a, A);
162             at = qu[front].a + temp;
163             bt = qu[front].b;
164             ct = qu[front].c;
165             dt = qu[front].d - temp;
166             if(EnterJudge(at, bt, ct, dt))
167                 step[at][bt][ct][dt] = 
168                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
169         }
170         if(qu[front].d > 0 && qu[front].b < B) //d向b倒水
171         {
172             temp = min(qu[front].d, qu[front].b, B);
173             at = qu[front].a;
174             bt = qu[front].b + temp;
175             ct = qu[front].c;
176             dt = qu[front].d - temp;
177             if(EnterJudge(at, bt, ct, dt))
178                 step[at][bt][ct][dt] = 
179                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
180         }
181         if(qu[front].d > 0 && qu[front].c < C) //d向c倒水
182         {
183             temp = min(qu[front].d, qu[front].c, C);
184             at = qu[front].a;
185             bt = qu[front].b;
186             ct = qu[front].c + temp;
187             dt = qu[front].d - temp;
188             if(EnterJudge(at, bt, ct, dt))
189                 step[at][bt][ct][dt] = 
190                 step[qu[front].a][qu[front].b][qu[front].c][qu[front].d] + 1; 
191         }
192     }
193 
194     return -1;
195 }
196 
197 int main()
198 {
199     memset(step, 0, sizeof(step));
200     memset(visit, 0, sizeof(visit));
201     
202     scanf("%d,%d,%d,%d", &ea, &eb, &ec, &ed);
203 
204     int cnt = bfs();
205 
206     printf("%d\n", cnt);
207 
208     return 0;
209 }
原文地址:https://www.cnblogs.com/Dreamcaihao/p/3053177.html