zoukankan      html  css  js  c++  java
  • HDU1495 非常可乐(BFS/数论)

    大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
    Input三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。Output如果能平分的话请输出最少要倒的次数,否则输出"NO"。Sample Input
    7 4 3
    4 1 3
    0 0 0
    Sample Output
    NO
    3

    BFS暴力搜索可解。倒水只可能有六种情况,s->m s->n m->s m-->n n->s n->m 每种情况里分为能把待倒入的瓶子倒满和不能倒满。这里可以用一个结构体记录信息:s代表原瓶里的可乐容量,m代表m瓶里的,n代表n瓶里的,nxt代表下一次要往外倒可乐的瓶号(0代表s瓶,1代表m瓶,2代表n瓶),cnt代表倒可乐累积的次数。再建立一个vis数组判断是否访问过。要注意的是这里最好建四维数组,三维存s,m,n,第四维存nxt。BFS即可,注释写得很详细。

    最后附上大佬的数论解法https://www.cnblogs.com/ECJTUACM-873284962/p/6750320.html

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    int s,n,m;
    struct node
    {
        int s;
        int m;
        int n;
        int cnt;
        int nxt;//下一次该哪个杯子往外倒水 0 s 1 m 2 n
    };     
    bool vis[105][105][105][4]={0};//四维vis数组存是否访问过 
    int bfs()
    {
        node start;
        start.s=s;
        start.n=0;//初始化第一层信息 
        start.m=0;
        start.cnt=0;
        start.nxt=0; 
        queue<node>q;
        q.push(start);
        memset(vis,0,sizeof(vis));
        while(q.size())
        {
            node pre=q.front();
            q.pop();
            if((pre.s==pre.n&&pre.s==s/2)||(pre.s==pre.m&&pre.s==s/2)||(pre.n==pre.m&&pre.n==s/2))//是否搜到 
            {
                return pre.cnt;
            }
            if(vis[pre.s][pre.m][pre.n][pre.nxt])//访问过的话直接continue 
            {
                continue;
            }
            vis[pre.s][pre.m][pre.n][pre.nxt]=1;
            int pour=pre.nxt;
            node next;
            if(pour==0)//s往n m倒水 
            {
                //s往n 
                if(n-pre.n<pre.s) //能倒满 
                {
                    next.s=pre.s-(n-pre.n);//更新下一层的信息 
                    next.m=pre.m;
                    next.n=n;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);//不为0的话再添加 要不然瓶子里都没可乐了也就倒不出来了 
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);//如果只是三维vis数组的话 加进去三个s m n一样但nxt不一样的 后两个都被vis判定卡掉了 所以要换成四维 
                }
                else if(n-pre.n>=s)//不能倒满 
                {
                    next.s=0;
                    next.m=pre.m;
                    next.n=pre.n+pre.s;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                //s往m 
                    if(m-pre.m<pre.s) 
                {
                    next.s=pre.s-(m-pre.m);
                    next.n=pre.n;
                    next.m=m;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                else if(m-pre.m>=pre.s) 
                {
                    next.s=0;
                    next.n=pre.n;
                    next.m=pre.m+pre.s;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                
            }
            else if(pour==1)//m往 s n 
            {
                //m往s 
                if(s-pre.s<pre.m) 
                {
                    next.m=pre.m-(s-pre.s);
                    next.n=pre.n;
                    next.s=s;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                else if(s-pre.s>=pre.m)
                {
                    next.m=0;
                    next.n=pre.n;
                    next.s=pre.s+pre.m;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                //m往n 
                    if(n-pre.n<pre.m) 
                {
                    next.m=pre.m-(n-pre.n);
                    next.s=pre.s;
                    next.n=n;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                else if(n-pre.n>=pre.m) 
                {
                    next.m=0;
                    next.s=pre.s;
                    next.n=pre.n+pre.m;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
            }
            else if(pour==2)//n往s m 
            {
                //n往s 
                if(s-pre.s<pre.n) 
                {
                    next.n=pre.n-(s-pre.s);
                    next.m=pre.m;
                    next.s=s;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                else if(s-pre.s>=pre.n)
                {
                    next.n=0;
                    next.m=pre.m;
                    next.s=pre.s+pre.n;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                //n往m 
                    if(m-pre.m<pre.n) 
                {
                    next.n=pre.n-(m-pre.m);
                    next.s=pre.s;
                    next.m=m;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
                else if(m-pre.m>=pre.n) 
                {
                    next.n=0;
                    next.s=pre.s;
                    next.m=pre.m+pre.n;
                    next.cnt=pre.cnt+1;
                    next.nxt=0;
                    if(next.s!=0)q.push(next);
                    next.nxt=1;
                    if(next.m!=0)q.push(next);
                    next.nxt=2;
                    if(next.n!=0)q.push(next);
                }
            }
        }
        return 0;
    }
    int main()
    {
        while(scanf("%d%d%d",&s,&m,&n)&&s&&n&&m)
        {
            if(s%2!=0)
            {
                cout<<"NO"<<endl;
                continue;
            }
            int ans=bfs();
            if(ans)
            {
                cout<<ans<<endl;
                continue;
            }
            else
            {
                cout<<"NO"<<endl;
                continue;
            }
        }
        return 0;
    }

  • 相关阅读:
    如何自动生成图片用于测试 pytorch(No image? No need image)
    深度学习中Dropout原理解析
    关于深度学习中的batch_size
    每日一问
    flask中使用ajax 处理前端请求,每隔一段时间请求不通的接口,结果展示同一页面
    flask中使用ajax 处理前端请求,每隔一段时间请求一次
    flask中使用ajax 处理前端请求,结果展示在同一页面,不点击页面不展示
    appium 使用name 定位报错 Locator Strategy 'name' is not supported for this session
    robot framework 中一条用例执行失败,终止其他用例执行
    python 实现定时任务
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/12322242.html
Copyright © 2011-2022 走看看