https://github.com/hustcc/canvas-nest.js

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;
}

 简化代码之后:

#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\n", 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;
}

 

 

  

 

posted @ 2017-02-03 21:50  坏小孩不坏  阅读(516)  评论(0编辑  收藏  举报