三个水杯-简单bfs

给你三个水杯的容量,只有第一杯里面装满水,其他两个水杯是空的,再输入三个目标值,问你是否能通过倒水达到这个目标,如果能,输入最少步数,如果不能,输出-1.

这题其实就是一个简单的BFS,以前感觉太麻烦了,一直不想写,今天终于AC了它。最后提示一下,BFS还是加上标记比较好。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

int v1,v2,v3,e1,e2,e3;
int book[100][100][100];
typedef struct
{
    int a,b,c,s;
}node;

void bfs()
{
    queue<node> q;
    node t;
    t.a = v1;
    t.b = 0;
    t.c = 0;
    t.s = 0;
    q.push(t);
    while(!q.empty())
    {
        if(q.front().a == e1 && q.front().b == e2 && q.front().c == e3)
        {
            printf("%d\n",q.front().s);
            return;
        }
        if(q.front().a == v1 && q.front().b == v2 && q.front().c == 0 && q.front().s != 0)
        {
            printf("-1\n");
            return;
        }
        t = q.front();
        q.pop();
        node n;
        if(t.a && t.b < v2)//ab
        {
            if(t.a >= (v2 - t.b))
            {
                n.a = t.a - (v2 - t.b);
                n.b = v2;
            }
            else
            {
                n.a = 0;
                n.b = t.b + t.a;
            }
            n.c = t.c;
            n.s = t.s + 1;
            if(book[n.a][n.b][n.c]==0)
            {
                book[n.a][n.b][n.c]=1;
                q.push(n);
            }

        }
        if(t.a && t.c < v3)//ac
        {
            if(t.a >= (v3 - t.c))
            {
                n.a = t.a - (v3 - t.c);
                n.c = v3;
            }
            else
            {
                n.a = 0;
                n.c = t.c + t.a;
            }
            n.b = t.b;
            n.s = t.s + 1;
            if(book[n.a][n.b][n.c]==0)
            {
                book[n.a][n.b][n.c]=1;
                q.push(n);
            }
        }

        if(t.b && t.a < v1)//ba
        {
            if(t.b >= (v1 - t.a))
            {
                n.b = t.b - (v1 - t.a);
                n.a = v1;
            }
            else
            {
                n.b = 0;
                n.a = t.a + t.b;
            }
            n.c = t.c;
            n.s = t.s + 1;
            if(book[n.a][n.b][n.c]==0)
            {
                book[n.a][n.b][n.c]=1;
                q.push(n);
            }
        }
        if(t.b && t.c < v3)//bc
        {
            if(t.b >= (v3 - t.c))
            {
                n.b = t.b - (v3 - t.c);
                n.c = v3;
            }
            else
            {
                n.b = 0;
                n.c = t.c + t.b;
            }
            n.a = t.a;
            n.s = t.s + 1;
            if(book[n.a][n.b][n.c]==0)
            {
                book[n.a][n.b][n.c]=1;
                q.push(n);
            }
        }

        if(t.c && t.a < v1)//ca
        {
            if(t.c >= (v1 - t.a))
            {
                n.c = t.c - (v1 - t.a);
                n.a = v1;
            }
            else
            {
                n.c = 0;
                n.a = t.a + t.c;
            }
            n.b = t.b;
            n.s = t.s + 1;
            if(book[n.a][n.b][n.c]==0)
            {
                book[n.a][n.b][n.c]=1;
                q.push(n);
            }
        }
        if(t.c && t.b < v2)//cb
        {
            if(t.c >= (v2 - t.b))
            {
                n.c = t.c - (v2 - t.b);
                n.b = v2;
            }
            else
            {
                n.c = 0;
                n.b = t.b + t.c;
            }
            n.a = t.a;
            n.s = t.s + 1;
            if(book[n.a][n.b][n.c]==0)
            {
                book[n.a][n.b][n.c]=1;
                q.push(n);
            }
        }
    }
    printf("-1\n");
}
int main(void)
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(book,0,sizeof(book));
        scanf("%d%d%d",&v1,&v2,&v3);
        scanf("%d%d%d",&e1,&e2,&e3);
        bfs();
    }

    return 0;

}
/*
2
6 3 1
4 1 1
9 3 2
7 1 1
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值