非常可乐

题意就是给你仨瓶子,一个是可乐瓶,两个空瓶,三个都能用,你要倒来倒去来用两个瓶子平分第一个瓶里的可乐,但是倒的时候只能把瓶子倒满。输出平分需要的最少步骤,若不能输出NO;

广搜把每一步的结果都记录下来,自己可以找点小数据在纸上试试就明白了,代码有点长思路很清晰。注意一下标记就可以了,没有太大坑点,主要在理解。

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <string.h>
#include <stack>
#define LL long long
#define mem(a) memset(a,0,sizeof(a))
int M,N,S,vis[105][105][105];
struct node
{
    int s,n,m,step;
};
std::queue<node> q;
int bfs()
{
    node a,t;
    int i,k;
    mem(vis);
    while(q.size())
        q.pop();
    a.s=S;
    a.m=0;
    a.n=0;
    a.step=0;
    q.push(a);
    vis[a.s][0][0]=1;
    while(q.size())
    {
        a=q.front();
        q.pop();
        if(a.s==S/2&&a.m==S/2||a.s==S/2&&a.n==S/2||a.m==S/2&&a.n==S/2)
            return a.step;
        for(i=0;i<6;i++)//倒可乐的循环步骤,光看是不容易理解的,自己找数据亲自试试,想想
        {
            if(i==0)///S-->M
            {
                k=a.s<(M-a.m)?a.s:(M-a.m);
                t.s=a.s-(M-a.m);
                t.m=a.m+k;
                t.n=a.n;
            }
            else if(i==1)///M-->S
            {
                k=a.m<(S-a.s)?a.m:(S-a.s);
                t.s=a.s+k;
                t.m=a.m-k;
                t.n=a.n;
            }
            else if(i==2)///S-->N
            {
                k=a.s<(N-a.n)?a.s:(N-a.n);
                t.s=a.s-k;
                t.n=a.n+k;
                t.m=a.m;
            }
            else if(i==3)///N-->S
            {
                k=a.n<(S-a.s)?a.n:(S-a.s);
                t.s=a.s+k;
                t.n=a.n-k;
                t.m=a.m;
            }
            else if(i==4)///M-->N
            {
                k=a.m<(N-a.n)?a.m:(N-a.n);
                t.s=a.s;
                t.m=a.m-k;
                t.n=a.n+k;
            }
            else///N-->M
            {
                k=a.n<(M-a.m)?a.n:(M-a.m);
                t.s=a.s;
                t.m=a.m+k;
                t.n=a.n-k;
            }
            if(!vis[t.s][t.m][t.n])
            {
                t.step=a.step+1;
                vis[t.s][t.m][t.n]=1;
                q.push(t);
            }
        }
    }
    return -1;
}
int main()
{
    while(scanf("%d%d%d",&S,&N,&M),M+S+N)
    {
        if(S%2>0)
            printf("NO
");
        else
        {
            int k=bfs();
            if(k!=-1)
                printf("%d
",k);
            else
                printf("NO
");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/nr1999/p/8485693.html