分酒问题

三个水杯

描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
输入
第一行一个整数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
#include<stdio.h>
typedef struct Node
{
    int a;
    int b;
    int c;
    int step;
}Node;
Node start;
Node temp;
int store[110][110][110];
int v1,v2,v3,e1,e2,e3;
Node queen[10000] = {0,0,0,0};
int front;
int rear;
void init()
{
    int i,j,k;  
    for(i = 0;i<110;i++)
        for(j = 0;j<110;j++)
            for(k = 0;k<110;k++)
                store[i][j][k] = 0;

}
void BFS()
{
    front = -1;
    rear = -1;
    start.a = v1;
    start.b = 0;
    start.c = 0;
    start.step = 0;
    queen[++rear] = start;
    store[v1][0][0] = 1;
    while(front != rear)
    {
        start = queen[++front];
        if(start.a == e1&&start.b == e2&&start.c == e3)
        {
             printf("%d\n",start.step); 
            return ;
        }
        //1->2
        if(start.a-(v2-start.b)>=0)
        {
            temp.a = start.a-(v2-start.b);
            temp.b = v2;
            temp.c = start.c;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }       
        }
        else
        {
            temp.a = 0;
            temp.b = start.b + start.a;
            temp.c = start.c;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }

        //1->3
        if(start.a-(v3-start.c)>0)
        {
            temp.a = start.a-(v3-start.c);
            temp.b = start.b;
            temp.c = v3;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }       
        }
        else
        {
            temp.a = 0;
            temp.b = start.b;
            temp.c = start.c + start.a; 
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }
        //2->3
        if(start.b-(v3-start.c)>0)
        {
            temp.a = start.a;
            temp.b = start.b-(v3-start.c);
            temp.c = v3;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }
        else
        {
            temp.a = start.a;
            temp.b = 0;
            temp.c = start.b+start.c;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }   
        }
        //2->1
        if(start.b-(v1-start.a)>0)
        {
            temp.a = v1;
            temp.b = start.b-(v1-start.a);
            temp.c = start.c;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }
        else
        {
            temp.a = start.a+start.b;
            temp.b = 0;
            temp.c = start.c;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }
        //3->1
        if(start.c-(v1-start.a)>0)
        {
            temp.a = v1;
            temp.b = start.b;
            temp.c = start.c-(v1-start.a);
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }
        else
        {
            temp.a = start.a+start.c;
            temp.b = start.b;
            temp.c = 0;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }
        //3->2
        if(start.c-(v2-start.b)>0)
        {
            temp.a = start.a;
            temp.b = v2;
            temp.c = start.c-(v2-start.b);
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }
        else
        {
            temp.a = start.a;
            temp.b = start.c+start.b;
            temp.c = 0;
            temp.step = start.step+1;
            if(store[temp.a][temp.b][temp.c] == 0)
            {
                store[temp.a][temp.b][temp.c] = 1;
                queen[++rear] = temp;
            }
        }

    }
    printf("-1\n"); 
    return ;
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d%d%d%d%d%d",&v1,&v2,&v3,&e1,&e2,&e3);
        //初始化状态数组
        init();
        //利用队列,广度搜索
        BFS();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值