M - 非常可乐

很明显看出来的广搜题目,不过因为有3个杯子相互倾倒,所以会产生6种倒发,比较冗杂,不过应该可以构造一个数组来解决这个问题,试试看吧
//////////////////////////////////////////////////////////////////
果然是可以的,用一个数组替代然后使用下标去表示

 

 #include<queue>

#include<stdio.h>
#include< string.h>
using  namespace std;

const  int maxn =  105;
const  int oo =  0xfffffff;

struct node{ int cup[ 3], step;};
node q;
int Full[ 3];
int dir[ 6][ 2] = { { 0, 1},{ 0, 2},{ 1, 0},{ 1, 2},{ 2, 0},{ 2, 1} };
int v[maxn][maxn][maxn];

void Turn( int &a,  int &b,  int FullB) // 把瓶子a里面的水倒入瓶子B
{
     if(a+b <= FullB)
        b += a, a= 0;
     else
    {
        a -= (FullB-b);
        b = FullB;
    }
}
int OK(node s) // 判断是否已经分好
{
     if(s.cup[ 0]+s.cup[ 1] == Full[ 0] && s.cup[ 0] == s.cup[ 1])
         return  1;
     if(s.cup[ 0]+s.cup[ 2] == Full[ 0] && s.cup[ 0] == s.cup[ 2])
         return  1;
     if(s.cup[ 1]+s.cup[ 2] == Full[ 0] && s.cup[ 1] == s.cup[ 2])
         return  1;

     return  0;
}
int Bfs(node s)
{
    queue<node> Q;
    Q.push(s);

     while(Q.size())
    {
        s = Q.front();Q.pop();

         if(OK(s))
             return s.step;

         for( int i= 0; i< 6; i++)
        {
            q = s;
            Turn(q.cup[ dir[i][ 0] ], q.cup[ dir[i][ 1] ], Full[dir[i][ 1]]);

             if(v[q.cup[ 0]][q.cup[ 1]][q.cup[ 2]] ==  0)
            {
                v[q.cup[ 0]][q.cup[ 1]][q.cup[ 2]] =  1;
                q.step++;
                Q.push(q);
            }
        }
    }

     return - 1;
}

int main()
{
    node s;

     while(scanf( " %d%d%d ", &Full[ 0], &Full[ 1], &Full[ 2]), Full[ 0]+Full[ 1]+Full[ 2])
    {
        memset(v,  0sizeof(v));

        s.cup[ 0] = Full[ 0];
        s.cup[ 1]=s.cup[ 2]=s.step= 0;
         int ans = Bfs(s);

         if(ans == - 1)
            printf( " NO\n ");
         else
            printf( " %d\n ", ans);
    }

     return  0;
}

你可能感兴趣的:(M - 非常可乐)