非常可乐

非常可乐
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
 

Input

三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
 

Output

如果能平分的话请输出最少要倒的次数,否则输出"NO"。
 

Sample Input

7 4 3 4 1 3 0 0 0
 

Sample Output

NO 3

保存每次能互相倒得状态,然后BFS,还算相对巧妙,之后多用用这么写。。。

代码有点长,可以适当封装下,不过这样也挺清晰的。。。

AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define MAX 10005
#define INF 0x3f3f3f3f
#define LL long long
#define pii pair<int,int>
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z)
///map<int,int>mmap;
///map<int,int >::iterator it;
using namespace std;
int vist[105][105][105],a,b,c;//a b c->S 可乐的体积 , N 和 M是两个杯子的容量

struct node
{
    int a,b,c;//分别表示可乐瓶子,杯子1,杯子2它们里面的可乐体积
    int step;//步数
};
int sum=0;

void bfs()
{
    queue<node>que;
    memset(vist,0,sizeof(vist));
    node p1;
    p1.a=a , p1.b=0 , p1.c=0 , p1.step=0;
    que.push(p1);
    vist[p1.a][0][0]=1;

    while(!que.empty())
    {
        p1=que.front();
        que.pop();
        if((p1.a==a/2&&p1.b==a/2)||(p1.a==a/2&&p1.c==a/2)||(p1.b==a/2&&p1.c==a/2))
        {
            printf("%d
",p1.step);
            return;
        }
        //
        node p2;
        if(p1.a!=0)
        {//a倒入b
            if(p1.a>b-p1.b)
            {
                p2.a=p1.a-(b-p1.b);
                p2.b=b;
                p2.c=p1.c;
                p2.step=p1.step+1;
            }
            else
            {
                p2.a=0;
                p2.b=p1.b+p1.a;
                p2.c=p1.c;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                que.push(p2);
            }
        }

        if(p1.a!=0)
        {//a倒入c
            if(p1.a>c-p1.c)
            {
                p2.a=p1.a-(c-p1.c);
                p2.b=p1.b;
                p2.c=c;
                p2.step=p1.step+1;
            }
            else
            {
                p2.a=0;
                p2.b=p1.b;
                p2.c=p1.c+p1.a;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                que.push(p2);
            }
        }

        if(p1.b!=0)
        {//b倒入a
            if(p1.b>a-p1.a)
            {
                p2.b=p1.b-(a-p1.a);
                p2.a=a;
                p2.c=p1.c;
                p2.step=p1.step+1;
            }
            else
            {
                p2.b=0;
                p2.a=p1.a+p1.b;
                p2.c=p1.c;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                que.push(p2);
            }
        }

        if(p1.b!=0)
        {//b倒入c
            if(p1.b>c-p1.c)
            {
                p2.b=p1.b-(c-p1.c);
                p2.a=p1.a;
                p2.c=c;
                p2.step=p1.step+1;
            }
            else
            {
                p2.b=0;
                p2.a=p1.a;
                p2.c=p1.c+p1.b;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                que.push(p2);
            }
        }

        if(p1.c!=0)
        {//c倒入a
            if(p1.c>a-p1.a)
            {
                p2.c=p1.c-(a-p1.a);
                p2.a=a;
                p2.b=p1.b;
                p2.step=p1.step+1;
            }
            else
            {
                p2.c=0;
                p2.a=p1.a+p1.c;
                p2.b=p1.b;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                que.push(p2);
            }
        }

        if(p1.c!=0)
        {//c倒入b
            if(p1.c>b-p1.b)
            {
                p2.c=p1.c-(b-p1.b);
                p2.a=p1.a;
                p2.b=b;
                p2.step=p1.step+1;
            }
            else
            {
                p2.c=0;
                p2.a=p1.a;
                p2.b=p1.b+p1.c;
                p2.step=p1.step+1;
            }
            if(!vist[p2.a][p2.b][p2.c])
            {
                vist[p2.a][p2.b][p2.c]=1;
                que.push(p2);
            }
        }
    }
    printf("NO
");
}



int main()
{
    while(~scanf("%d%d%d",&a,&b,&c))
    {

        if(a==0&&b==0&&c==0)  break;
        if(a%2==1)
        {
            printf("NO
");
            continue;
        }
        bfs();
    }
    return 0;
}





原文地址:https://www.cnblogs.com/zswbky/p/6717986.html