nyist_21(三个水杯)(BFS)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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, 23,
分为为: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)的主要内容,如果未能解决你的问题,请参考以下文章

Nyoj 21 三个水杯(bfs)

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

NYOJ-三个水杯

C++宽搜经典题——三个水杯(一题懂宽搜!)

三个水杯(BFS)

三个水杯(BFS)