zoukankan      html  css  js  c++  java
  • 蓝桥杯-分红酒

                                      分红酒

      有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

     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
    ");
    50             continue;
    51         }
    52         if(end.num[0] + end.num[1] + end.num[2] + end.num[3] != 9)//一共分的是9升酒,输入不合法
    53         {
    54             printf("-1
    ");
    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
    " , 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 }
  • 相关阅读:
    020-请你说一说app测试的工具
    栈的压入、弹出序列
    包含min函数的栈
    顺时针打印矩阵
    二叉树的镜像
    树的子结构
    链表中倒数第k个结点
    调整数组顺序使奇数位于偶数前面
    数值的整数次方
    矩形覆盖
  • 原文地址:https://www.cnblogs.com/youdiankun/p/3616297.html
Copyright © 2011-2022 走看看