HDU 1495 非常可乐(搜索)

题目链接:[原题](http://acm.hdu.edu.cn/showproblem.php?pid=1495)
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>

using namespace std;
//定义Node存放a,b,c杯里的水的体积count记录操作次数 
struct Node{
    int a,b,c,count;
};
bool V[103][103][103];
void BFS(int S,int N,int M){
    memset(V,false,sizeof(V));

    Node temp,start; //temp储存改变状态后的节点 start储存开始的节点
    queue< Node > Que;
    //开始时只有S
    start.a=S; start.b=0; start.c=0; start.count=0;

    Que.push(start);      
    //如果是非空队列 
    while(!Que.empty()){

        start=Que.front();//把第一个元素给temp 
        Que.pop();        //弹出第一个元素 
        V[start.a][start.b][start.c]=true;//标记此节点 

        if((start.a==S/2 && start.b==S/2)||
           (start.b==S/2 && start.c==S/2)||
           (start.a==S/2 && start.c==S/2) )
        {   
            printf("%d\n",start.count);
            return;
        }

        //3个杯子相互倒水有6种情况
        //a->b a->c b->a b->c c->a c->b
        //a->S b->N c->M 
        //如果a杯子里有水
        if(start.a !=0 ){
            //a杯向b杯倒水有两种情况
            //如果a能把b倒满 
            if(start.a > N-start.b){
                temp.a=start.a-(N-start.b);
                temp.b=N;
                temp.c=start.c;
                temp.count=start.count+1;
            }
            else{
                temp.a=0;
                temp.b=start.a+start.b;
                temp.c=start.c;
                temp.count=start.count+1;
            }
            //如果这个状态没有走过 
            if(!V[temp.a][temp.b][temp.c]){
                V[temp.a][temp.b][temp.c]=true;

                Que.push(temp);
            }


            //a杯向c杯倒水有两种情况
            //如果a杯能把c杯倒满
            if(start.a > M-start.c){
                temp.a=start.a-(M-start.c);
                temp.b=start.b;
                temp.c=M;
                temp.count=start.count+1;
            }
            else{
                temp.a=0;
                temp.b=start.b;
                temp.c=start.c+start.a;
                temp.count=start.count+1;
            }
            if(!V[temp.a][temp.b][temp.c]){
                V[temp.a][temp.b][temp.c]=true;
                Que.push(temp);
            }
        }

        //如果b杯里面有水 
        if(start.b!=0){
            //b杯向a杯倒水有两种情况
            //如果b能把a倒满 
            if(start.b > S-start.a){
                temp.a=S;
                temp.b=start.b-(S-start.a);
                temp.c=start.c;
                temp.count=start.count+1;
            }
            else{
                temp.a=start.b+start.a;
                temp.b=0;
                temp.c=start.c;
                temp.count=start.count+1;
            }
            if(!V[temp.a][temp.b][temp.c]){
                V[temp.a][temp.b][temp.c]=true;
                Que.push(temp);
            }

            //b杯向c杯倒水有两种情况
            //如果b杯能把c杯倒满
            if(start.b > M-start.c){
                temp.a=start.a;
                temp.b=start.b-(M-start.c);
                temp.c=M;
                temp.count=start.count+1;
            }
            else{
                temp.a=start.a;
                temp.b=0;
                temp.c=start.c+start.b;
                temp.count=start.count+1;
            }
            if(!V[temp.a][temp.b][temp.c]){
                V[temp.a][temp.b][temp.c]=true;
                Que.push(temp);
            }
        }

        //如果c杯里面有水 
        if(start.c!=0){
            //c杯向a杯倒水有两种情况
            //如果c能把a倒满 
            if(start.c > S-start.a){
                temp.a=S;
                temp.b=start.b;
                temp.c=start.c-(S-start.a);
                temp.count=start.count+1;
            }
            else{
                temp.a=start.c+start.a;
                temp.b=start.b;
                temp.c=0;
                temp.count=start.count+1;
            }
            if(!V[temp.a][temp.b][temp.c]){
                V[temp.a][temp.b][temp.c]=true;
                Que.push(temp);
            }

            //如果c杯能把b杯倒满
            if(start.c > N-start.b){
                temp.a=start.a;
                temp.b=N;
                temp.c=start.c-(N-start.b);
                temp.count=start.count+1;
            }
            else{
                temp.a=start.a;
                temp.b=start.b+start.c;
                temp.c=0;
                temp.count=start.count+1;
            }
            if(!V[temp.a][temp.b][temp.c]){
                V[temp.a][temp.b][temp.c]=true;
                Que.push(temp);
            }
        }
    }
    printf("NO\n");
    return;
}
int main(){
    int s,n,m;
    while(scanf("%d%d%d",&s,&n,&m)!=EOF){
        if((s+n+m)==0) break;
        //如果s是奇数那是不可能平分的 
        if(s & 1)   printf("NO\n");
        else
            BFS(s,n,m);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值