首页 > 代码库 > nyist_21(三个水杯)(BFS)
nyist_21(三个水杯)(BFS)
描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
输入
第一行一个整数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
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=21
思路分析:
总共三个杯子,所以在一次选择的时候,共有6种方案,此处设杯子的标号为1, 2, 3, 分为为:1->2, 2->1, 1->3, 3->1, 2->3, 3->2这六种方案可供选择,而每种方案又出现 了被倒的杯子会不会被倒满这两种情况。因为本着简单处理,所以写了6个大选择,每个大选择 里面又会出现两种小选择。将每次倒水之后的三个杯子的状态进行标记,有效地进行剪枝,最后 用BFS实现迭代,然后找到符合条件的情况时,输出当前时间,即为最小的次数,所以还有创建 结构体用来存放三个杯子的水量和当前的时间。大体思路就是如此,不懂可以相互讨论,方法比 较好懂,是给看者提供思路而已。
具体代码:
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> using namespace std; struct Status{ int first; int second; int third; int time; }bg,ed; int v1, v2, v3; bool vis[105][105][105]; void BFS(Status s){ queue<Status> que; que.push(s); memset(vis, false, sizeof(vis)); vis[bg.first][0][0] = true; while(que.empty() == false){ Status s1 = que.front(), s2; que.pop(); if(s1.first == ed.first && s1.second == ed.second && s1.third == ed.third){ printf("%d\n", s1.time); return; } if(s1.first != 0 && s1.second != v2){// 1 -> 2 if(s1.first + s1.second > v2){//倒不尽 s2.first = s1.first - (v2 - s1.second); s2.second = v2; }else{//倒得尽 s2.first = 0; s2.second = s1.first + s1.second; } s2.third = s1.third; if(vis[s2.first][s2.second][s2.third] == false){ s2.time = s1.time + 1; que.push(s2); vis[s2.first][s2.second][s2.third] = true; } } if(s1.second != 0 && s1.first != v1){// 2 -> 1 if(s1.first + s1.second > v1){//倒不尽 s2.second = s1.second - (v1 - s1.first); s2.first = v1; }else{//倒得尽 s2.second = 0; s2.first = s1.first + s1.second; } s2.third = s1.third; if(vis[s2.first][s2.second][s2.third] == false){ s2.time = s1.time + 1; que.push(s2); vis[s2.first][s2.second][s2.third] = true; } } if(s1.first != 0 && s1.third != v3){// 1 -> 3 if(s1.first + s1.third > v3){//倒不尽 s2.first = s1.first - (v3 - s1.third); s2.third = v3; }else{//倒得尽 s2.first = 0; s2.third = s1.first + s1.third; } s2.second = s1.second; if(vis[s2.first][s2.second][s2.third] == false){ s2.time = s1.time + 1; que.push(s2); vis[s2.first][s2.second][s2.third] = true; } } if(s1.third != 0 && s1.first != v1){// 3 -> 1 if(s1.first + s1.third > v1){//倒不尽 s2.third = s1.third - (v1 - s1.first); s2.first = v1; }else{//倒得尽 s2.third = 0; s2.first = s1.first + s1.third; } s2.second = s1.second; if(vis[s2.first][s2.second][s2.third] == false){ s2.time = s1.time + 1; que.push(s2); vis[s2.first][s2.second][s2.third] = true; } } if(s1.second != 0 && s1.third != v3){// 2 -> 3 if(s1.second + s1.third > v3){//倒不尽 s2.second = s1.second - (v3 - s1.third); s2.third = v3; }else{//倒得尽 s2.second = 0; s2.third = s1.second + s1.third; } s2.first = s1.first; if(vis[s2.first][s2.second][s2.third] == false){ s2.time = s1.time + 1; que.push(s2); vis[s2.first][s2.second][s2.third] = true; } } if(s1.third != 0 && s1.second != v2){// 3 -> 2 if(s1.second + s1.third > v2){//倒不尽 s2.third = s1.third - (v2 - s1.second); s2.second = v2; }else{//倒得尽 s2.third = 0; s2.second = s1.second + s1.third; } s2.first = s1.first; if(vis[s2.first][s2.second][s2.third] == false){ s2.time = s1.time + 1; que.push(s2); vis[s2.first][s2.second][s2.third] = true; } } } puts("-1"); } int main(){ int T; scanf("%d", &T); while(T--){ scanf("%d%d%d", &v1, &v2, &v3); scanf("%d%d%d", &ed.first, &ed.second, &ed.third); if(v1 != ed.first + ed.second + ed.third){ puts("-1"); continue; } bg.first = v1; bg.second = bg.third = bg.time = 0; BFS(bg); } return 0; }
nyist_21(三个水杯)(BFS)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。