zoukankan      html  css  js  c++  java
  • nyoj 21-三个水杯(BFS)

    21-三个水杯


    内存限制:64MB 时间限制:1000ms Special Judge: No
    accepted:7 submit:18

    题目描述:

    给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。

    输入描述:

    第一行一个整数N(0<N<50)表示N组测试数据
    接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
    第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态

    输出描述:

    每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1

    样例输入:

    2
    6 3 1
    4 1 1
    9 3 2
    7 1 1

    样例输出:

    3
    -1

    分析:
      ①、题目要求的是最少的倒水次数,即就是最短步数问题;
      ②、对上一步产生的结果下一步应该怎样应对,用队列来考虑每一步的结果;
      ③、用BFS的思想模拟,每一次(从6种倒水可能中进行抉择与判断)倒水将会参会什么样的结果

    步骤:
      ①、初始化队列的首相,即就是最开始的水的分配情况
      ②、循环6步操作,考虑同样的水在6中不同情况下的分配如何,分别入队列
      ③、依次遍历出所有的情况,如果可以得到结果的话,就输出步骤,否则如果遍历完了都没能得到结果就return -1

    核心代码:
      
     1 int bfs()
     2 {
     3     queue<node> Q;
     4     node q1, q2;
     5     memset(book, 0, sizeof(book));
     6     q1.temp[0] = A[0], q1.temp[1] = 0, q1.temp[2] = 0;
     7     book[q1.temp[0]][0][0] = 1;
     8     Q.push(q1);
     9     while(!Q.empty())
    10     {
    11         q1 = Q.front();
    12         if(q1.temp[0] == B[0] && q1.temp[1] == B[1]
    13             && q1.temp[2] == B[2])
    14             return q1.step;
    15         for(int i = 0; i < 3; ++ i)
    16         {
    17             for(int j = 0; j < 3; ++ j)
    18             {
    19                 if (i == j) continue; // 自己不向自己倒水
    20                 q2 = q1;
    21                 int my_change = min(q1.temp[i], A[j] - q1.temp[j]); // 将i杯中的水倒入j杯,A[j] - q1.temp[j],表明j杯最多可以得到的水量
    22                 q2.temp[i] = q1.temp[i] - my_change;
    23                 q2.temp[j] = q1.temp[j] + my_change;
    24                 q2.step = q1.step + 1;
    25                 if(!book[q2.temp[0]][q2.temp[1]][q2.temp[2]])
    26                 {
    27                     book[q2.temp[0]][q2.temp[1]][q2.temp[2]];
    28                     Q.push(q2);
    29                 }
    30             }
    31         }
    32         Q.pop();
    33     }
    34     return -1;
    35 }
    
    

    C/C++代码实现(AC):

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <stack>
     7 #include <map>
     8 #include <queue>
     9 
    10 using namespace std;
    11 const int MAXN = 110;
    12 int A[5], B[5], book[MAXN][MAXN][MAXN];
    13 struct node
    14 {
    15     int temp[3], step;
    16 };
    17 
    18 bool match(node q, int a, int b, int c)
    19 {
    20     if(q.temp[0] == a && q.temp[1] == b && q.temp[2] == c) return true;
    21     return false;
    22 }
    23 
    24 int bfs()
    25 {
    26     node q1, q2;
    27     q1.temp[0] = A[0], q1.temp[1] = 0, q1.temp[2] = 0, q1.step = 0;
    28     queue<node> Q;
    29     Q.push(q1);
    30     memset(book, 0, sizeof(book));
    31     book[A[0]][0][0] = 1;
    32     while(!Q.empty())
    33     {
    34         q1 = Q.front();
    35         if(match(q1, B[0], B[1], B[2])) return q1.step;
    36         for(int i = 0; i < 3; ++ i) // 倒水的方式有6种
    37         {
    38             for(int j = 0; j < 3; ++ j)
    39             {
    40                 if(i == j) continue;
    41                 int my_op = min(q1.temp[i], A[j] - q1.temp[j]); // 将i杯子里面的水倒到j杯子中
    42                 q2 = q1;
    43                 q2.temp[i] = q1.temp[i] - my_op;
    44                 q2.temp[j] = q1.temp[j] + my_op;
    45                 q2.step ++;
    46                 if(!book[q2.temp[0]][q2.temp[1]][q2.temp[2]])
    47                 {
    48                     book[q2.temp[0]][q2.temp[1]][q2.temp[2]] = 1;
    49                     Q.push(q2);
    50                 }
    51             }
    52         }
    53         Q.pop();
    54     }
    55     return -1;
    56 }
    57 
    58 int main()
    59 {
    60     int t;
    61     scanf("%d", &t);
    62     while(t --)
    63     {
    64         memset(book, 0, sizeof(book));
    65         scanf("%d%d%d", &A[0], &A[1], &A[2]);
    66         scanf("%d%d%d", &B[0], &B[1], &B[2]);
    67         printf("%d
    ", bfs());
    68     }
    69     return 0;
    70 }
    
    
  • 相关阅读:
    关于Asp.net应用程序生命周期
    xmlHttpRequest 以Post方式发数据到Asp.net页,在gb2312编码下的解决办法
    Asp.net中TreeView gb2312状态PopulateNodesFromClient乱码问题
    Subsonic中的MarkOld与MarkNew的一些使用
    非递归一次性加载分类数据到TreeViw
    Atitit rss没落以及替代品在线阅读器
    Atitit 2016年attilax事业成就表
    Atitit HTTP 认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结Atitit HT
    Atitit 项目语言的选择 java c#.net  php??
    atitit 商业项目常用模块技术知识点 v3 qc29
  • 原文地址:https://www.cnblogs.com/GetcharZp/p/9065090.html
Copyright © 2011-2022 走看看