21-三个水杯

内存限制:64MB
时间限制:1000ms
Special Judge: No

accepted:7
submit:18

题目描述:

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

输入描述:

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

输出描述:

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

样例输入:

复制

  1. 2
  2. 6 3 1
  3. 4 1 1
  4. 9 3 2
  5. 7 1 1

样例输出:

  1. 3
  2. -1
  3.  
  4. 分析:
      ①、题目要求的是最少的倒水次数,即就是最短步数问题;
      ②、对上一步产生的结果下一步应该怎样应对,用队列来考虑每一步的结果;
      ③、用BFS的思想模拟,每一次(从6种倒水可能中进行抉择与判断)倒水将会参会什么样的结果
  5. 步骤:
      ①、初始化队列的首相,即就是最开始的水的分配情况
      ②、循环6步操作,考虑同样的水在6中不同情况下的分配如何,分别入队列
      ③、依次遍历出所有的情况,如果可以得到结果的话,就输出步骤,否则如果遍历完了都没能得到结果就return -1
  6. 核心代码:
      
  1. int bfs()
  2. {
  3. queue<node> Q;
  4. node q1, q2;
  5. memset(book, , sizeof(book));
  6. q1.temp[] = A[], q1.temp[] = , q1.temp[] = ;
  7. book[q1.temp[]][][] = ;
  8. Q.push(q1);
  9. while(!Q.empty())
  10. {
  11. q1 = Q.front();
  12. if(q1.temp[] == B[] && q1.temp[] == B[]
  13. && q1.temp[] == B[])
  14. return q1.step;
  15. for(int i = ; i < ; ++ i)
  16. {
  17. for(int j = ; j < ; ++ 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 + ;
  25. if(!book[q2.temp[]][q2.temp[]][q2.temp[]])
  26. {
  27. book[q2.temp[]][q2.temp[]][q2.temp[]];
  28. Q.push(q2);
  29. }
  30. }
  31. }
  32. Q.pop();
  33. }
  34. return -;
  35. }
  1.  

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 = ;
  12. int A[], B[], book[MAXN][MAXN][MAXN];
  13. struct node
  14. {
  15. int temp[], step;
  16. };
  17.  
  18. bool match(node q, int a, int b, int c)
  19. {
  20. if(q.temp[] == a && q.temp[] == b && q.temp[] == c) return true;
  21. return false;
  22. }
  23.  
  24. int bfs()
  25. {
  26. node q1, q2;
  27. q1.temp[] = A[], q1.temp[] = , q1.temp[] = , q1.step = ;
  28. queue<node> Q;
  29. Q.push(q1);
  30. memset(book, , sizeof(book));
  31. book[A[]][][] = ;
  32. while(!Q.empty())
  33. {
  34. q1 = Q.front();
  35. if(match(q1, B[], B[], B[])) return q1.step;
  36. for(int i = ; i < ; ++ i) // 倒水的方式有6种
  37. {
  38. for(int j = ; j < ; ++ 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[]][q2.temp[]][q2.temp[]])
  47. {
  48. book[q2.temp[]][q2.temp[]][q2.temp[]] = ;
  49. Q.push(q2);
  50. }
  51. }
  52. }
  53. Q.pop();
  54. }
  55. return -;
  56. }
  57.  
  58. int main()
  59. {
  60. int t;
  61. scanf("%d", &t);
  62. while(t --)
  63. {
  64. memset(book, , sizeof(book));
  65. scanf("%d%d%d", &A[], &A[], &A[]);
  66. scanf("%d%d%d", &B[], &B[], &B[]);
  67. printf("%d\n", bfs());
  68. }
  69. return ;
  70. }
  1.  

nyoj 21-三个水杯(BFS)的更多相关文章

  1. nyoj 21三个水杯(BFS + 栈)

    题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=21 思想: 看了一下搜索就来写了这题(BFS 找出最短路径 所以用此来进行搜索) 这题在 ...

  2. NYOJ 21.三个水杯-初始态到目标态的最少次数-经典BFS

    题目传送门:biubiubiu~ 三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子. ...

  3. NYOJ #21 三个水杯(bfs)

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

  4. NYOJ 21 三个水杯

    三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有 ...

  5. nyoj三个水杯(bfs)

    三个水杯 时间限制:1000 ms  |           内存限制:65535 KB 难度:4   描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互 ...

  6. nyoj 题目21 三个水杯

    三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有 ...

  7. 三个水杯 (bfs)

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

  8. nyoj 三个水杯

    三个水杯 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只 ...

  9. 三个水杯(BFS)

    三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描写叙述 给出三个水杯.大小不一,而且仅仅有最大的水杯的水是装满的,其余两个为空杯子. 三个水杯之间相互倒水,而且水杯 ...

随机推荐

  1. 关于vue使用的一些小经验

    这一年来说,vue的势头很猛,用户量“噌”“噌”“噌”的涨 为了不掉队不落伍.在后台大哥的胁迫下,不得不选择用了它 刚开始很难接受vue的写法,在编辑器里很容易报错,基本上每行都会出现红色的波浪线 这 ...

  2. html简介(1)

    HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言: HyperText Markup Language HTML 不是一种编程语言,而是一种标记语言

  3. Python编程系列---装饰器执行的底层原理及流程

    代码中No.1  No.2 ...表示执行流程 """No.1 No.2 ...表示执行流程""" def set_func(func): ...

  4. linux 基本操作--笔记

    linux 基本操作: pwd 显示当前目录 ll 用于查看文件和目录,即list,其参数比较多 -l 列出数据串,包含文件的属性和权限数据等 -a 列出全部文件,包含隐藏文件 -d 仅列出目录本身, ...

  5. Log4j slf4j 配置简单介绍

    Log4j slf4j 配置简单介绍 先借鉴一篇很好的文章 为什么要使用SLF4J而不是Log4J import org.slf4j.Logger; import org.slf4j.LoggerFa ...

  6. Linux常用命令及示例(全)

    NO 分类 PS1 命令名 用法及参数 功能注解1 显示目录信息 # ls ls -a 列出当前目录下的所有文件,包括以.头的隐含文件 # ls ls -l或ll 列出当前目录下文件的详细信息 # l ...

  7. Java基础(十八)集合(5)Queue集合

    队列是只能在尾部添加元素,同时只能在头部删除元素的数据结构.队列的原则就是“先进先出”. Queue接口是Collection接口的最后一个子接口. Queue接口是队列接口,而Deque接口是Que ...

  8. Gitlab在Centos7上的安装

    一 官网说明 安装步骤:https://about.gitlab.com/install/#centos-7 安装说明:本文只是用来给微服务当配置中心,只是较浅的记录一下安装步骤,后面会详细讲解及在d ...

  9. K8s 还是 k3s?This is a question

    本文来自:Rancher Labs 自k3s问世以来,社区里有许多小伙伴都问过这样的问题"除了中间的数字之外,k3s和K8s的区别在哪里?","在两者之间应该如何选择?& ...

  10. 在docker中创建使用MySQL,并实现远程连接navicat

    在 docker 中使用 mysql 安装完docker之后,在命令行中输入docker images可以查看自己创建的image(安装下载docker的教程很多了,大家需要可以去查一下就可以了)这里 ...