首页 > 代码库 > NYOJ 21 三个水杯
NYOJ 21 三个水杯
三个水杯
时间限制:1000 ms | 内存限制:65535 KB
难度:4
- 描述
- 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
- 输入
- 第一行一个整数N(0<N<50)表示N组测试数据 接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。 第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态
- 输出
- 每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1
- 样例输入
26 3 14 1 19 3 27 1 1
- 样例输出
3-1
原题出自:http://acm.nyist.net/JudgeOnline/problem.php?pid=21
简单的宽度优先搜索,三个水杯之间的相互倒水如下图6种情况:对于每一次倒水都会引起三个水杯水量状态的改变,这样就可以得到如下的一个解空间树:
代码一:比较容易想到的
1 #include<cstring> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cstdlib> 6 using namespace std; 7 8 int v1, v2, v3; 9 bool visit[105][105][105]; //状态是否出现 10 11 struct state 12 { 13 int a, b, c; 14 int ceng; //最小步数 15 }b, e; 16 17 int BFS() 18 { 19 queue<state> q; 20 while(!q.empty()) 21 q.pop(); 22 q.push(b); 23 while(!q.empty()) 24 { 25 state cur = q.front(); 26 q.pop(); 27 visit[cur.a][cur.b][cur.c] = true; 28 29 if(cur.a == e.a && cur.b == e.b && cur.c == e.c) //找到 30 return cur.ceng; 31 32 if(cur.a > 0 && cur.b < v2) //v1->v2 33 { 34 state temp = cur; 35 int tt = min(temp.a, v2 - temp.b); 36 temp.a -= tt; 37 temp.b += tt; 38 if(visit[temp.a][temp.b][temp.c] == false) 39 { 40 visit[temp.a][temp.b][temp.c] = true; 41 temp.ceng++; 42 q.push(temp); 43 } 44 } 45 46 if(cur.a > 0 && cur.c < v3) //v1->v3 47 { 48 state temp = cur; 49 int tt = min(temp.a, v3 - temp.c); 50 temp.a -= tt; 51 temp.c += tt; 52 if(visit[temp.a][temp.b][temp.c] == false) 53 { 54 visit[temp.a][temp.b][temp.c] = true; 55 temp.ceng++; 56 q.push(temp); 57 } 58 } 59 60 if(cur.b > 0 && cur.a < v1) //v2->v1 61 { 62 state temp = cur; 63 int tt = min(temp.b, v1 - temp.a); 64 temp.a += tt; 65 temp.b -= tt; 66 if(visit[temp.a][temp.b][temp.c] == false) 67 { 68 visit[temp.a][temp.b][temp.c] = true; 69 temp.ceng++; 70 q.push(temp); 71 } 72 } 73 74 if(cur.b > 0 && cur.c < v3) //v2->v3 75 { 76 state temp = cur; 77 int tt = min(temp.b, v3 - temp.c); 78 temp.b -= tt; 79 temp.c += tt; 80 if(visit[temp.a][temp.b][temp.c] == false) 81 { 82 visit[temp.a][temp.b][temp.c] = true; 83 temp.ceng++; 84 q.push(temp); 85 } 86 } 87 88 if(cur.c > 0 && cur.a < v1) //v3->v1 89 { 90 state temp = cur; 91 int tt = min(temp.c, v1 - temp.a); 92 temp.c -= tt; 93 temp.a += tt; 94 if(visit[temp.a][temp.b][temp.c] == false) 95 { 96 visit[temp.a][temp.b][temp.c] = true; 97 temp.ceng++; 98 q.push(temp); 99 }100 }101 102 if(cur.c > 0 && cur.b < v2) //v3->v2103 {104 state temp = cur;105 int tt = min(temp.c, v2 - temp.b);106 temp.c -= tt;107 temp.b += tt;108 if(visit[temp.a][temp.b][temp.c] == false)109 {110 visit[temp.a][temp.b][temp.c] = true;111 temp.ceng++;112 q.push(temp);113 }114 }115 }116 return -1; //没有终状态117 }118 119 int main()120 {121 int n;122 scanf("%d", &n);123 while(n--)124 {125 memset(visit, false, sizeof(visit));126 scanf("%d %d %d", &v1, &v2, &v3);127 b.a = v1, b.b = 0, b.c = 0, b.ceng = 0;128 scanf("%d %d %d", &e.a, &e.b, &e.c);129 if(v1 < e.a + e.b + e.c)130 {131 printf("-1\n");132 continue;133 }134 else135 printf("%d\n", BFS());136 }137 return 0;138 }
方法二:Floyd 算法
1 #include <cstdio> 2 #include <memory.h> 3 #include <queue> 4 5 using namespace std; 6 7 #define EMPTY 0 8 9 struct data_type 10 { 11 int state[3]; 12 int step; 13 }; 14 15 int cupCapacity[3], targetState[3]; 16 17 bool visited[100][100][100]; 18 19 bool AchieveTargetState(data_type current) 20 { 21 for (int i = 0; i < 3; i++) 22 { 23 if (current.state[i] != targetState[i]) 24 { 25 return false; 26 } 27 } 28 return true; 29 } 30 31 void PourWater(int destination, int source, data_type &cup) 32 { 33 int waterYield = cupCapacity[destination] - cup.state[destination]; 34 if (cup.state[source] >= waterYield) 35 { 36 cup.state[destination] += waterYield; 37 cup.state[source] -= waterYield; 38 } 39 else 40 { 41 cup.state[destination] += cup.state[source]; 42 cup.state[source] = 0; 43 } 44 } 45 46 int BFS(void) 47 { 48 int i, j, k; 49 data_type initial; 50 queue<data_type> toExpandState; 51 52 memset(visited, false, sizeof(visited)); 53 initial.state[0] = cupCapacity[0]; 54 initial.state[1] = initial.state[2] = 0; 55 initial.step = 0; 56 toExpandState.push(initial); 57 visited[initial.state[0]][0][0] = true; 58 59 while (!toExpandState.empty()) 60 { 61 data_type node = toExpandState.front(); 62 toExpandState.pop(); 63 if (AchieveTargetState(node)) 64 { 65 return node.step; 66 } 67 for (i = 0; i < 3; i++) 68 { 69 for (j = 1; j < 3; j++) 70 { 71 k = (i+j)%3; 72 if (node.state[i] != EMPTY && node.state[k] < cupCapacity[k]) 73 { 74 data_type newNode = node; 75 PourWater(k, i, newNode); 76 newNode.step = node.step + 1; 77 if (!visited[newNode.state[0]][newNode.state[1]][newNode.state[2]]) 78 { 79 visited[newNode.state[0]][newNode.state[1]][newNode.state[2]] = true; 80 toExpandState.push(newNode); 81 } 82 } 83 } 84 } 85 } 86 return -1; 87 } 88 89 int main(void) 90 { 91 int testNum; 92 scanf("%d", &testNum); 93 while (testNum -- != 0) 94 { 95 scanf("%d%d%d", &cupCapacity[0], &cupCapacity[1], &cupCapacity[2]); 96 scanf("%d%d%d", &targetState[0], &targetState[1], &targetState[2]); 97 printf("%d\n", BFS()); 98 } 99 return 0;100 }
转自:http://blog.csdn.net/code_pang/article/details/7802944
NYOJ 21 三个水杯
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。