zoukankan      html  css  js  c++  java
  • 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
    ", 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;
    }

     简化代码之后:

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    using  namespace std;
    
    struct Status{
        int water[3];
        int time;
    }bg,ed;
    int v[3];
    bool vis[105][105][105];
    int dir[6][3] = {{0, 1, 2}, {1, 0, 2}, {0, 2, 1}, {2, 0, 1}, {1, 2, 0}, {2, 1, 0}};
    int d[6] = {1, 0, 2, 0, 2, 1};
    
    void BFS(Status s){
        
        queue<Status> que;
        que.push(s);
        memset(vis, false, sizeof(vis));
        vis[bg.water[0]][0][0] = true;
        while(que.empty() == false){
            Status s1 = que.front(), s2;
            que.pop();
            if(s1.water[0] == ed.water[0] && s1.water[1] == ed.water[1] && s1.water[2] == ed.water[2]){
                printf("%d
    ", s1.time);
                return;
            }
            for(int i=0; i<6; i++){
                if(s1.water[dir[i][0]] != 0 && s1.water[dir[i][1]] != v[d[i]]){// 1 -> 2
                    if(s1.water[dir[i][0]] + s1.water[dir[i][1]] > v[d[i]]){//倒不尽 
                        s2.water[dir[i][0]] = s1.water[dir[i][0]] - (v[d[i]] - s1.water[dir[i][1]]);
                        s2.water[dir[i][1]] = v[d[i]];
                    }else{//倒得尽 
                        s2.water[dir[i][0]] = 0;
                        s2.water[dir[i][1]] = s1.water[dir[i][0]] + s1.water[dir[i][1]];
                    }
                    s2.water[dir[i][2]] = s1.water[dir[i][2]]; 
                    if(vis[s2.water[0]][s2.water[1]][s2.water[2]] == false){
                        s2.time = s1.time + 1;
                        que.push(s2);
                        vis[s2.water[0]][s2.water[1]][s2.water[2]] = true;
                    }
                }
            }
        }
        puts("-1");
    }
     
    int main(){
        
        int T;
        scanf("%d", &T);    
        while(T--){
            for(int i=0; i<3; i++)
                scanf("%d", &v[i]);
            scanf("%d%d%d", &ed.water[0], &ed.water[1], &ed.water[2]);
            if(v[0] != ed.water[0] + ed.water[1] + ed.water[2]){
                puts("-1");
                continue;
            }
            bg.water[0] = v[0];
            bg.water[1] = bg.water[2] = bg.time = 0;
            BFS(bg);
        }
        return 0;
    }
     

      

  • 相关阅读:
    JSP内置对象
    Java数据结构
    Java引用传递
    椭圆曲线算法的基本原理及实现
    常见的Java异常
    Java数据结构
    Java数据结构
    重拾JSP
    [洛谷P6185] [NOI online 提高]T1 序列
    [题解][BZOJ1299]巧克力棒
  • 原文地址:https://www.cnblogs.com/huaixiaohai2015/p/6363552.html
Copyright © 2011-2022 走看看