非常可乐 (HDU 1495)——BFS

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495
题目大意:一瓶S的可乐,两个容量分别为N和M的杯子,三者能够相互倾倒可乐,并且S=M+N,问是否能得到相同的两份可乐。如果能的话就计算最少的操作步数。

题解:就是有六种操作,然后就用常规bfs来做。每种操作额外考虑一下能否倒完就好了。

2021/3/16 (新帖简洁代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>

using namespace std;

int read() {
    int x = 0, f = 1; char ch = getchar();
    while(ch < '0' || ch > '9') { if(ch == '-') f = -f; ch = getchar(); }
    while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

const int maxN = 101;
int ini[3], mid;
bool vis[maxN][maxN][maxN];
int dir[6][2] = {
    0, 1,
    0, 2,
    1, 0,
    1, 2,
    2, 0,
    2, 1
};
struct node{
    int a[3], dis;
};
int bfs() {
    queue<node>q;
    q.push(node{{ini[0], 0, 0}, 0});
    vis[ini[0]][0][0] = true;
    while(!q.empty()) {
        node tmp = q.front(); q.pop();
        for(int i = 0; i < 6; ++ i ) {
            node New = tmp; New.dis += 1;
            int fir = dir[i][0], sec = dir[i][1];
            int dif = min(New.a[fir], ini[sec] - New.a[sec]);
            New.a[fir] -= dif, New.a[sec] += dif;
            if(vis[New.a[0]][New.a[1]][New.a[2]]) continue;
            q.push(New);
            vis[New.a[0]][New.a[1]][New.a[2]] = true;
            if(New.a[0] == New.a[2] && New.a[0] == mid && New.a[1] == 0) return New.dis;
            if(New.a[1] == New.a[2] && New.a[1] == mid && New.a[0] == 0) return New.dis;
            if(New.a[0] == New.a[1] && New.a[0] == mid && New.a[2] == 0) return New.dis;
        }
    }
    return -1;
}

int main() {
    while(~scanf("%d%d%d", &ini[0], &ini[1], &ini[2]) && (ini[0] || ini[1] || ini[2])) {
        if(ini[0] & 1) {
            puts("NO");
            continue;
        }
        memset(vis, false, sizeof(vis));
        if(ini[1] > ini[2]) swap(ini[1], ini[2]);
        mid = ini[0] >> 1;
        int ans = bfs();
         if(ans == -1) {
            puts("NO");
            continue;
        }
        printf("%d\n", ans);
    }
    return 0;
}

FEELING:debug了很久,本来昨天做了一道类似的而且还比这个难,但是这个还是做了一个多小时,debug了贼久,然后最后发现是有个最后一种操作的字母有地方写错了,天呐,也真的是……不然另一道题就开出来了,室友等我回去还是要走了,呜呜呜,伤心……

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <math.h>
#include <string.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <map>

#define INF 0x3f3f3f3f
const int MAX=0x3f3f3f3f;

using namespace std;
typedef long long ll;
int S,N,M;
struct node{
    int s,n,m;//当前状态
    int step;//步数
};
int mp[105][105][105];

int bfs(int es,int en,int em)
{
    memset(mp,false,sizeof(mp));
    node temp;
    temp.s=es;
    temp.n=en;
    temp.m=em;
    temp.step=0;
    queue<node>q;
    q.push(temp);
    mp[q.front().s][q.front().n][q.front().m]=1;
    while(!q.empty())
    {
        for(int i=0;i<6;i++)
        {
            if(i==0)//S->N
            {
                //如果能倒完
                if(q.front().s<=N-q.front().n)
                {
                    temp.n=q.front().n+q.front().s;
                    temp.s=0;
                    temp.m=q.front().m;
                }
                //如果不能倒完
                else if(q.front().s>N-q.front().n)
                {
                    temp.s=q.front().s-(N-q.front().n);
                    temp.n=N;
                    temp.m=q.front().m;
                }
            }
            else if(i==1)//S->M
            {
                //如果能倒完
                if(q.front().s<=M-q.front().m)
                {
                    temp.m=q.front().m+q.front().s;
                    temp.s=0;
                    temp.n=q.front().n;
                }
                    //如果不能倒完
                else if(q.front().s>M-q.front().m)
                {
                    temp.s=q.front().s-(M-q.front().m);
                    temp.m=M;
                    temp.n=q.front().n;
                }
            }
            else if(i==2)//N->S
            {
                //如果能倒完
                if(q.front().n<=S-q.front().s)
                {
                    temp.s=q.front().n+q.front().s;
                    temp.n=0;
                    temp.m=q.front().m;
                }
                    //如果不能倒完
                else if(q.front().n>S-q.front().s)
                {
                    temp.n=q.front().n-(S-q.front().s);
                    temp.s=S;
                    temp.m=q.front().m;
                }
            }
            else if(i==3)//N->M
            {
                //如果能倒完
                if(q.front().n<=M-q.front().m)
                {
                    temp.m=q.front().n+q.front().m;
                    temp.n=0;
                    temp.s=q.front().s;
                }
                    //如果不能倒完
                else if(q.front().n>M-q.front().m)
                {
                    temp.n=q.front().n-(M-q.front().m);
                    temp.m=M;
                    temp.s=q.front().s;
                }
            }
            else if(i==4)//M->S
            {
                //如果能倒完
                if(q.front().m<=S-q.front().s)
                {
                    temp.s=q.front().m+q.front().s;
                    temp.m=0;
                    temp.n=q.front().n;
                }
                    //如果不能倒完
                else if(q.front().m>S-q.front().s)
                {
                    temp.m=q.front().m-(S-q.front().s);
                    temp.s=S;
                    temp.n=q.front().n;
                }
            }
            else if(i==5)//M->N
            {
                //如果能倒完
                if(q.front().m<=N-q.front().n)
                {
                    temp.n=q.front().n+q.front().m;
                    temp.m=0;
                    temp.s=q.front().s;
                }
                    //如果不能倒完
                else if(q.front().m>N-q.front().n)
                {
                    temp.m=q.front().m-(N-q.front().n);
                    temp.n=N;
                    temp.s=q.front().s;
                }
            }
            if(mp[temp.s][temp.n][temp.m]==1)
                continue;
            temp.step=q.front().step+1;
            q.push(temp);
            mp[temp.s][temp.n][temp.m]=1;
            if((temp.s==temp.n&&temp.m==0)||(temp.s==temp.m&&temp.n==0)||(temp.m==temp.n&&temp.s==0))
                return temp.step;
        }
        q.pop();
    }
    return 0;
}

int main()
{
    while(~scanf("%d%d%d",&S,&N,&M)&&(S||N||M))
    {
        int ans=bfs(S,0,0);
        if(ans==0)
            printf("NO\n");
        else
            printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值