HDU - 1495 非常可乐 —— bfs

9 篇文章 0 订阅

思路:

有三个容器,每个最大是100,共有100*100*100=1e6种状态,深搜记录一下每种状态和这种状态的最小步数

深搜时遍历每个容器,如果这个容器里有可乐,就尝试着倒入另外两个容器里

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define max_ 10010
#define mod 100000007
#define inf 0x3f3f3f3f
struct node
{
    int a,b,c;
    int step;
    node(int a_,int b_,int c_,int t_)
    {
        a=a_;b=b_;c=c_;step=t_;
    }
};
int s,n,m;
queue<struct node>q;
int vis[105][105][105];
bool judge(node zz)
{
    if(zz.a==s/2&&zz.b==s/2)
    return true;
    if(zz.a==s/2&&zz.c==s/2)
    return true;
    if(zz.b==s/2&&zz.c==s/2)
    return true;
    return false;
}
int main(int argc, char const *argv[]) {
    while(scanf("%d%d%d",&s,&n,&m)!=EOF)
    {
        if(s==0&&n==0&&m==0)
        break;
        memset(vis,inf,sizeof vis);
        while(!q.empty())
        q.pop();
        if(s&1)
        {
            printf("NO\n");
            continue;
        }
        q.push(node(s,0,0,0));
        vis[s][0][0]=0;
        int f=0;
        while(!q.empty())
        {
            node zz=q.front();
            q.pop();
            if(judge(zz))
            {
                printf("%d\n",zz.step);
                f=1;
                break;
            }
            if(zz.a!=0)
            {
                int aa=max(0,zz.a+zz.b-n),bb=min(zz.a+zz.b,n),cc=zz.c,step=zz.step+1;
                if(vis[aa][bb][cc]>step)
                vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
                aa=max(0,zz.a+zz.c-m),bb=zz.b,cc=min(zz.a+zz.c,m);
                if(vis[aa][bb][cc]>step)
                vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
            }
            if(zz.b!=0)
            {
                int aa=min(s,zz.a+zz.b),bb=max(0,zz.a+zz.b-s),cc=zz.c,step=zz.step+1;
                if(vis[aa][bb][cc]>step)
                vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
                aa=zz.a,bb=max(0,zz.b+zz.c-m),cc=min(m,zz.b+zz.c);
                if(vis[aa][bb][cc]>step)
                vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
            }
            if(zz.c!=0)
            {
                int aa=min(s,zz.a+zz.c),bb=zz.b,cc=max(0,zz.a+zz.c-s),step=zz.step+1;
                if(vis[aa][bb][cc]>step)
                vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
                aa=zz.a,bb=min(n,zz.b+zz.c),cc=max(0,zz.b+zz.c-n);
                if(vis[aa][bb][cc]>step)
                vis[aa][bb][cc]=step,q.push(node(aa,bb,cc,step));
            }
        }
        if(!f)
        printf("NO\n");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值