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\n", bfs());
68     }
69     return 0;
70 }


原文地址:https://www.cnblogs.com/GetcharZp/p/9065090.html

时间: 2024-07-30 01:53:33

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

NYOJ 21 三个水杯 【暴力+BFS】

题意:不解释. 策略:广搜. 解释一下为什么会是广搜,一个水杯只能向其他两个水杯倒水,不能向他自己倒水,这样一共有三个水杯也就是有6种情况,只需要一步一步的搜索就好了(数据没多大 <100), 我们将每一次出现的水杯中的水数(就是有多少水)都标记下来,如果是以前没有出现过,那么就进队列,同时将此时的水杯数标记下来,说明该种情况已出现,一直找到想要找的状态为止,如果都找不到,就返回-1. 难点:我在下面的代码中会有详细的解释. ps:网上有说这道题是隐式图,因为BFS原来是来搜索图的,我比较认可.

Nyoj 21 三个水杯(bfs)

三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数. 输入 第一行一个整数N(0<N<50)表示N组测试数据接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的

BFS [NYOJ 21] 三个水杯

三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数. 输入 第一行一个整数N(0<N<50)表示N组测试数据接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的

nyoj 21 三个水杯

三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数. 输入 第一行一个整数N(0<N<50)表示N组测试数据接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的

队列,广搜 nyoj 21 三个水杯

三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数. 输入 第一行一个整数N(0<N<50)表示N组测试数据 接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯

nyoj三个水杯(bfs)

三个水杯 时间限制:1000 ms  |           内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数. 输入 第一行一个整数N(0<N<50)表示N组测试数据接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>

nyist_21(三个水杯)(BFS)

描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数. 输入 第一行一个整数N(0<N<50)表示N组测试数据 接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积. 第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们

NYOJ21 三个水杯 (经典问题 bfs)

题目描述: http://acm.nyist.net/JudgeOnline/problem.php?pid=21 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数. 输入 第一行一个整数N(0<N<50)表示N组测试数据 接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100

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

题目传送门:biubiubiu~ 三个水杯 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算.现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数. 输入 第一行一个整数N(0<N<50)表示N组测试数据接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<10