非常可乐---hdu 1495(BFS)

http://acm.hdu.edu.cn/showproblem.php?pid=1495

题意:

有3个杯子a b c;a=b+c;然后刚开始时只有a是满的,其它为空的,然后a b c三个之间互相倒,假如说a倒入b中,只有当b满或a空时,才算倒一次;

a=4,b=1;c=3;

因为刚开始只有a中有;

先让a倒入c中3;step++;

c倒入b中1;step++;

b倒入a中1;step++;此时a和c中各有2;

代码如下:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#define N 120
using namespace std;

struct node
{
    int a,b,c,step;
    friend bool operator<(node a,node b)
    {
        return a.step>b.step;
    }
};
int vis[N][N][N];
int BFS(int a,int b,int c)
{
    node q,p;
    priority_queue<node>Q;
    memset(vis,0,sizeof(vis));
    p.a=a;p.b=0;p.c=0;p.step=0;
    vis[p.a][p.b][p.c]=1;
    Q.push(p);
    while(!Q.empty())
    {
        q=Q.top();
        Q.pop();
        if((q.a==a/2&&q.b==a/2)||(q.b==a/2&&q.c==a/2)||(q.a==a/2&&q.c==a/2) )
            return q.step;
        if(q.a!=0)//a->其他;
        {
            if(q.a<=b-q.b)//a->b;如果a中的全都能倒到b中;
            {
                p.a=0;
                p.b=a-q.c;
                p.c=q.c;
                p.step=q.step+1;
            }
            else//a不能全到完;因为b满了;
            {
                p.a=a-b-q.c;
                p.b=b;
                p.c=q.c;
                p.step=q.step+1;
            }
            if(vis[p.a][p.b][p.c]==0)
            {
                vis[p.a][p.b][p.c]=1;
                Q.push(p);
            }

            //以下同理;
            if(q.a<=b-q.c)//a->c;如果a中的全都能倒到c中;
            {
                p.a=0;
                p.b=q.b;
                p.c=a-q.b;
                p.step=q.step+1;
            }
            else//a不能全到完;因为c满了;
            {
                p.a=a-c-q.b;
                p.b=q.b;
                p.c=c;
                p.step=q.step+1;
            }
            if(vis[p.a][p.b][p.c]==0)
            {
                vis[p.a][p.b][p.c]=1;
                Q.push(p);
            }
        }

        if(q.b!=0)//b->其他;
        {
            if(q.b<=a-q.a)//b->a;如果b中的全都能倒到a中;
            {
                p.a=a-q.c;
                p.b=0;
                p.c=q.c;
                p.step=q.step+1;
            }

            if(vis[p.a][p.b][p.c]==0)
            {
                vis[p.a][p.b][p.c]=1;
                Q.push(p);
            }

            //以下同理;
            if(q.b<=c-q.c)//b->c;如果b中的全都能倒到c中;
            {
                p.a=q.a;
                p.b=0;
                p.c=a-q.a;
                p.step=q.step+1;
            }
            else//b不能全到完;因为c满了;
            {
                p.a=q.a;
                p.b=a-q.a-c;
                p.c=c;
                p.step=q.step+1;
            }
            if(vis[p.a][p.b][p.c]==0)
            {
                vis[p.a][p.b][p.c]=1;
                Q.push(p);
            }
        }

        if(q.c!=0)//c->其他;
        {
            if(q.c<=a-q.a)//c->a;如果c中的全都能倒到a中;
            {
                p.a=a-q.b;
                p.b=q.b;
                p.c=0;
                p.step=q.step+1;
            }

            if(vis[p.a][p.b][p.c]==0)
            {
                vis[p.a][p.b][p.c]=1;
                Q.push(p);
            }

            //以下同理;
            if(q.c<=b-q.b)//c->b;如果c中的全都能倒到b中;
            {
                p.a=q.a;
                p.b=a-q.a;
                p.c=0;
                p.step=q.step+1;
            }
            else//c不能全到完;因为b满了;
            {
                p.a=q.a;
                p.b=b;
                p.c=a-q.a-b;
                p.step=q.step+1;
            }
            if(vis[p.a][p.b][p.c]==0)
            {
                vis[p.a][p.b][p.c]=1;
                Q.push(p);
            }
        }
    }
    return -1;
}

int main()
{
    int a,b,c,ans;
    while(scanf("%d%d%d",&a,&b,&c),a+b+c)
    {
        if(a%2==1)
        {
            printf("NO
");
            continue;
        }
        else
        {
            ans=BFS(a,b,c);
            if(ans==-1)
                printf("NO
");
            else
                printf("%d
",ans);
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4515568.html