首页 > 其他 > 详细

蓝桥杯-分红酒

时间:2014-03-22 03:29:59      阅读:636      评论:0      收藏:0      [点我收藏+]

                                  分红酒

  有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

 

bubuko.com,布布扣
 1 #include <cstdio>
 2 #include <queue>
 3 #include <string.h>
 4 using namespace std;
 5 
 6 int full[4] = {9 , 7 , 4 , 2};
 7 typedef struct
 8 {
 9     int num[4];
10     int step;
11 }state;
12 
13 int vis[10][8][5][3];
14 int bfs(state &temp , int i , int j)//把i倒入j中
15 {
16     if(i == j) return 0;
17     if(temp.num[i] == 0) return 0;//如果i空,不用倒了
18     if(temp.num[j] == full[j]) return 0;//如果j满,不用倒了
19     if(temp.num[i] + temp.num[j] <=full[j])
20     {
21         temp.num[j] = temp.num[j] + temp.num[i];//把i全倒入j中,此时i空
22         temp.num[i] = 0;
23     }
24     else
25     {
26         temp.num[i] = temp.num[i] - (full[j] - temp.num[j]);//把i的一部分倒入j中,倒到j满
27         temp.num[j] = full[j];
28     }
29     if(vis[temp.num[0]][temp.num[1]][temp.num[2]][temp.num[3]]) return 0;//如果之前出现过这种情况,就不再反复倒了
30     vis[temp.num[0]][temp.num[1]][temp.num[2]][temp.num[3]] = 1;
31     temp.step++;
32     return 1;
33 }
34 int main()
35 {
36     state start , end;
37     start.num[0] = 9;
38     start.num[1] = 0;
39     start.num[2] = 0;
40     start.num[3] = 0;
41     start.step = 0;
42     while(scanf("%d%d%d%d",&end.num[0],&end.num[1],&end.num[2],&end.num[3])!=EOF)
43     {
44         memset(vis , 0 , sizeof(vis));
45         queue<state>q;
46         q.push(start);
47         if(end.num[0]>full[0] || end.num[1]>full[1] || end.num[2]>full[2] || end.num[3]>full[3])//给定的目标状态>瓶子容量
48         {
49             printf("-1\n");
50             continue;
51         }
52         if(end.num[0] + end.num[1] + end.num[2] + end.num[3] != 9)//一共分的是9升酒,输入不合法
53         {
54             printf("-1\n");
55             continue;
56         }
57         while(!q.empty())
58         {
59             state temp , temp1;
60             temp = q.front();
61             q.pop();
62             if(temp.num[0]==end.num[0] && temp.num[1]==end.num[1] && temp.num[2]==end.num[2] && temp.num[3]==end.num[3])
63             {
64                 printf("%d\n" , temp.step);
65                 break;
66             }
67             int i , j;
68             for(i = 0; i < 4; i++)//把i倒入j中
69             {
70                 for(j = 0; j < 4; j++)
71                 {
72                     temp1 = temp;
73                     if(bfs(temp1 , i , j))
74                     {
75                         q.push(temp1);
76                     }
77                 }
78             }
79         }
80     }
81     return 0;
82 }
bubuko.com,布布扣

蓝桥杯-分红酒,布布扣,bubuko.com

蓝桥杯-分红酒

原文:http://www.cnblogs.com/youdiankun/p/3616297.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!