HDU1495-非常可乐

题目链接:hdu1495

如果做过前面那个倒水的题目(POJ3414),那么这道题就简化成了,3个杯子互相倒水,只用输出最少的次数,而不用输出路径。简化版倒水题。

记得用一个vis[maxn][maxn][maxn]数组来剪枝,免得T。

对了,还有一个默认的条件,平分指的是总水量平分,所以奇数不用考虑了。

ACcode:


#include<stdio.h>
#include<set>
#include<queue>
#include<string.h>
using namespace std;
int a,b,c;
const int maxn=110;
bool vis[maxn][maxn][maxn];//用来剪枝

struct bottle{
    int va,vb,vc;
    int step;
};

int bfs(){
    memset(vis,false,sizeof(vis));
    queue<bottle> q;
    bottle t1,t2,t3;
    t1.va=a;
    t1.vb=0;
    t1.vc=0;
    t1.step=0;
    vis[a][0][0]=1;
    q.push(t1);
    while(!q.empty()){
        t2=q.front();
        q.pop();
        int ca=t2.va;
        int cb=t2.vb;
        int cc=t2.vc;
       // printf("ca=%d,cb=%d,cc=%d\n",ca,cb,cc);
        if((ca==cb&&ca!=0&&cc==0)||(ca==cc&&ca!=0&&cb==0)||(cb==cc&&cb!=0&&ca==0)){//这里有点坑哦
            //    printf("r:%d %d %d\n",ca,cb,cc);
                return t2.step;
        }
        for(int i=0;i<6;i++){
            if(i==0){//a->b
                if(ca==0) continue;
                else{
                    t3.va=max(0,ca-(b-cb));
                    t3.vb=min(b,cb+ca);
                    t3.vc=cc;
                    t3.step=t2.step+1;
                    if(!vis[t3.va][t3.vb][t3.vc]){
                        q.push(t3);
                    //    printf("%d:%d %d %d\n",i,t3.va,t3.vb,t3.vc);
                        vis[t3.va][t3.vb][t3.vc]=1;
                    }
                }
            }else if(i==1){//a->c
                if(ca==0) continue;
                else{
                    t3.va=max(0,ca-(c-cc));
                    t3.vb=cb;
                    t3.vc=min(c,cc+ca);
                    t3.step=t2.step+1;
                   if(!vis[t3.va][t3.vb][t3.vc]){
                        q.push(t3);
                      //  printf("%d:%d %d %d\n",i,t3.va,t3.vb,t3.vc);
                        vis[t3.va][t3.vb][t3.vc]=1;
                    }
                }

            }else if(i==2){//b->c
                if(cb==0) continue;
                else{
                    t3.va=ca;
                    t3.vb=max(0,cb-(c-cc));
                    t3.vc=min(c,cc+cb);
                    t3.step=t2.step+1;
                    if(!vis[t3.va][t3.vb][t3.vc]){
                        q.push(t3);
                     //   printf("%d:%d %d %d\n",i,t3.va,t3.vb,t3.vc);
                        vis[t3.va][t3.vb][t3.vc]=1;
                    }
                }
            }else if(i==3){//b->a
                if(cb==0) continue;
                else{
                    t3.va=min(a,ca+cb);
                    t3.vb=max(0,cb-(a-ca));
                    t3.vc=cc;
                    t3.step=t2.step+1;
                    if(!vis[t3.va][t3.vb][t3.vc]){
                        q.push(t3);
                     //   printf("%d:%d %d %d\n",i,t3.va,t3.vb,t3.vc);
                        vis[t3.va][t3.vb][t3.vc]=1;
                    }
                }

            }else if(i==4){//c->b
                if(cc==0) continue;
                else{
                    t3.va=ca;
                    t3.vb=min(b,cb+cc);
                    t3.vc=max(0,cc-(b-cb));
                    t3.step=t2.step+1;
                    if(!vis[t3.va][t3.vb][t3.vc]){
                        q.push(t3);
                       // printf("%d:%d %d %d\n",i,t3.va,t3.vb,t3.vc);
                        vis[t3.va][t3.vb][t3.vc]=1;
                    }
                }
            }else if(i==5){//c->a
                if(cc==0) continue;
                else{
                    t3.va=min(a,ca+cc);
                    t3.vb=cb;
                    t3.vc=max(0,cc-(a-ca));
                    t3.step=t2.step+1;
                    if(!vis[t3.va][t3.vb][t3.vc]){
                        q.push(t3);
                      //  printf("%d:%d %d %d\n",i,t3.va,t3.vb,t3.vc);
                        vis[t3.va][t3.vb][t3.vc]=1;
                    }
                }
            }

        }
    }
    return 0;
}

int main(){
    while(scanf("%d%d%d",&a,&b,&c)==3&&a){
        if(a&1) printf("NO\n");
        else{
            int ans=bfs();
            if(ans) printf("%d\n",ans);
            else printf("NO\n");
        }

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值