hdu 杭电 1495 非常可乐

题意:容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。能平分的话请输出最少要倒的次数,否则输出"NO"。

 

解法:广搜,每一个队头元素都要进行6次操作,如图进行了n->m一次操作:

对应的6中操作(S->N,S->M,N->S,N->M,M->S,M->N)
此图必须注意:n,m的意思为:瓶子n中此刻存在的可乐量为n,瓶子m中此刻存在的可乐量为m

 

注意:从一个瓶倒进另一个瓶时必须分两种情况,1:能装满2:不能装满

 

ac代码及测试数据:

View Code
#include<iostream>
#include<queue>
using namespace std;

const int m=101;
int map[m][m][m];  //map[]用作标记

struct node
{
    int s,n,m;
    int step;
};

int main()
{
    queue<struct node>q;
    struct node temp;
    int s,n,m;
    int a,b,c;

    while(cin>>s>>n>>m,(s&&n&&m))
    {

        if(s%2==1||(s/2>n&&s/2>m)) //s若为奇数或s的一半都大于n,m.不可能满足条件,直接退出
        {
            cout<<"NO"<<endl;
            continue;
        }

        if(m>n)  //确保s>n>m
        {
            c=n;
            n=m;
            m=c;
        }

        memset(map,0,sizeof(map));

        a=temp.s=s;
        b=temp.n=0;
        c=temp.m=0;
        temp.step=0;
        map[a][b][c]=1;
        q.push(temp);  

        while(!q.empty())
        {
            if(q.front().m==s/2&&q.front().n==s/2&&q.front().s==0) 
            {
                cout<<q.front().step<<endl;
                break;
            }            
            if(q.front().m==0&&q.front().n==s/2&&q.front().s==s/2)  
            {
                cout<<q.front().step<<endl;
                break;
            }
            if(q.front().m==s/2&&q.front().n==0&&q.front().s==s/2)  
            {
                cout<<q.front().step<<endl;
                break;
            }
            //前三个if()判断是否满足条件



            if(q.front().s>=n-q.front().n)
            {
                a=q.front().s-(n-q.front().n);
                b=n;
                temp.s=a;
                temp.n=b;
                temp.m=q.front().m;
                if(!map[a][b][q.front().m])
                {
                    map[a][b][q.front().m]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }
            else                      
            {
                a=0;
                b=q.front().n+q.front().s;
                temp.s=a;
                temp.n=b;
                temp.m=q.front().m;
                if(!map[a][b][q.front().m])
                {
                    map[a][b][q.front().m]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }



            if(q.front().s>=m-q.front().m)
            {
                a=q.front().s-(m-q.front().m);
                c=m;
                temp.s=a;
                temp.m=c;
                temp.n=q.front().n;
                if(!map[a][q.front().n][c])
                {
                    map[a][q.front().n][c]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }
            else                      
            {
                a=0;
                b=q.front().n+q.front().s;
                temp.s=a;
                temp.n=b;
                temp.m=q.front().m;
                if(!map[a][b][q.front().m])
                {
                    map[a][b][q.front().m]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }


            if(s-q.front().s>q.front().n)
            {
                a=q.front().n+q.front().s;
                b=0;
                temp.s=a;
                temp.n=b;
                temp.m=q.front().m;
                if(!map[a][b][q.front().m])
                {
                    map[a][b][q.front().m]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }


            if(q.front().n>=m-q.front().m)
            {
                b=q.front().n-(m-q.front().m);
                c=m;
                temp.n=b;
                temp.m=c;
                temp.s=q.front().s;
                if(!map[q.front().s][b][c])
                {
                    map[q.front().s][b][c]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }
            else                      
            {
                b=0;
                c=q.front().m+q.front().n;
                temp.n=b;
                temp.m=c;
                temp.s=q.front().s;
                if(!map[q.front().s][b][c])
                {
                    map[q.front().s][b][c]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }


            if(s-q.front().s>q.front().m)
            {
                a=q.front().m+q.front().s;
                c=0;
                temp.s=a;
                temp.m=c;
                temp.n=q.front().n;
                if(!map[a][q.front().n][c])
                {
                    map[a][q.front().n][c]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }


            if(q.front().m>=n-q.front().n)
            {
                c=q.front().m-(n-q.front().n);
                b=n;
                temp.m=c;
                temp.n=b;
                temp.s=q.front().s;
                if(!map[q.front().s][b][c])
                {
                    map[q.front().s][b][c]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }
            else                      
            {
                c=0;
                b=q.front().n+q.front().m;
                temp.m=c;
                temp.n=b;
                temp.s=q.front().s;
                if(!map[q.front().s][b][c])
                {
                    map[q.front().s][b][c]=1;
                    temp.step=q.front().step+1;
                    q.push(temp);
                }
            }
            q.pop();
        }
        if(q.empty())
            cout<<"NO"<<endl;
        while(!q.empty())
            q.pop();
    }
    return 0;
}





峰注:不明白请留言

 


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值