南阳oj 题目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
样例输入
2
6 3 1
4 1 1
9 3 2
7 1 1
样例输出
3
-1
┭┮﹏┭┮
最笨的方法广搜,对杯子的水进行相互倒水,情况有(1->2)(2->1)(1->3)(3->1)(2->3)(3->2)六种情况,用队列保存每次转移后的状态,进行转移,知道找到目标状态就结束,或没有找到(-1)结束.当然如果目标状态的水杯水量和原来的水量不一样就没必要在经行搜索转移了。
特别注意的就是在转移过程中,会有将一个水杯的水全部倒入一个杯子和,将另一个杯子倒满,杯子有剩余,两种情况。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
struct node
{
    int x,y,z,num;
}as,t,h;
int a[110][110][110];
int n,m,k,n1,m1,k1;
queue<node>p;
void dfs()
{
    while(!p.empty())
        p.pop();
    as.x=n;
    as.y=0;
    as.z=0;
    as.num=0;
    p.push(as);
    memset(a,0,sizeof(a));
    a[as.x][0][0]=1;
    while(!p.empty())
    {
        h=p.front();
        p.pop();
        if(h.x==n1&&h.y==m1&&h.z==k1)
        {
            printf("%d\n",h.num);
            return ;
        }
        if(h.x!=0&&h.y!=m)//从第一个向第二个倒水
        {
            if(h.x+h.y>m)//如果第二个杯子放不下
            {
                t.x=h.x-(m-h.y);
                t.y=m;
            }
            else//如果第二个杯子能放下
            {
                t.x=0;
                t.y=h.x+h.y;
            }
            t.z=h.z;
            if(a[t.x][t.y][t.z]==0)//判断这种情况是否存在
            {
                t.num=h.num+1;
                p.push(t);
                a[t.x][t.y][t.z]=1;
            }
        }
        if(h.y!=0&&h.x!=n)//从第二个杯子向第一个杯子倒水
        {
            if(h.x+h.y>n)
            {
                t.y=h.y-(n-h.x);
                t.x=n;
            }
            else
            {
                t.y=0;
                t.x=h.x+h.y;
            }
            t.z=h.z;
            if(a[t.x][t.y][t.z]==0)
            {
                t.num=h.num+1;
                p.push(t);
                a[t.x][t.y][t.z]=1;
            }
        }
        if(h.x!=0&&h.z!=k)//从第一个杯子向第三个杯子倒水
        {
            if(h.x+h.z>k)
            {
                t.x=h.x-(k-h.z);
                t.z=k;
            }
            else
            {
                t.x=0;
                t.z=h.x+h.z;
            }
            t.y=h.y;
            if(a[t.x][t.y][t.z]==0)
            {
                t.num=h.num+1;
                p.push(t);
                a[t.x][t.y][t.z]=1;
            }
        }
        if(h.z!=0&&h.x!=n)//从第三个杯子向第一个杯子倒水
        {
            if(h.x+h.z>n)
            {
                t.z=h.z-(n-h.x);
                t.x=n;
            }
            else
            {
                t.z=0;
                t.x=h.x+h.z;
            }
            t.y=h.y;
            if(a[t.x][t.y][t.z]==0)
            {
                t.num=h.num+1;
                p.push(t);
                a[t.x][t.y][t.z]=1;
            }
        }
        if(h.y!=0&&h.z!=k)//第二个向第三个杯子倒水
        {
            if(h.z+h.y>k)
            {
                t.y=h.y-(k-h.z);
                t.z=k;
            }
            else
            {
                t.y=0;
                t.z=h.z+h.y;
            }
            t.x=h.x;
            if(a[t.x][t.y][t.z]==0)
            {
                t.num=h.num+1;
                p.push(t);
                a[t.x][t.y][t.z]=1;
            }
        }
        if(h.z!=0&&h.y!=m)//第三个杯子向第二个杯子倒水
        {
            if(h.z+h.y>m)
            {
                t.z=h.z-(m-h.y);
                t.y=m;
            }
            else
            {
                t.z=0;
                t.y=h.z+h.y;
            }
            t.x=h.x;
            if(a[t.x][t.y][t.z]==0)
            {
                t.num=h.num+1;
                p.push(t);
                a[t.x][t.y][t.z]=1;
            }
        }
    }
    printf("-1\n");
}
int main()
{
    int l;
    scanf("%d",&l);
    while(l--)
    {
        scanf("%d%d%d%d%d%d",&n,&m,&k,&n1,&m1,&k1);
        if(n!=n1+m1+k1)
            printf("-1\n");
        else
            dfs();
    }
    return 0;
}
posted @ 2017-05-10 21:25  南风古  阅读(229)  评论(0编辑  收藏  举报