HDU 1495 非常可乐【bfs】

非常可乐

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24662    Accepted Submission(s): 9580


 

Problem Description

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是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

 

 

Author

seeyou

 

 

Source

“2006校园文化活动月”之“校庆杯”大学生程序设计竞赛暨杭州电子科技大学第四届大学生程序设计竞赛

 

 

Recommend

LL

 

将三个容器内的可乐剩余容量看为三个坐标,即可转换为(x,y,z) 形态,然后就可以当做广搜来做。

 

题目所说的平分指的是包括可乐瓶本身在内的任意两个容器的可乐量相等,并且另外一个容器的剩余可乐容量为0.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
using namespace std;
#define LL long long
#define M(a,b) memset(a,b,sizeof(a))
const int MAXN = 1e2+5;
const int INF =  0x3f3f3f3f;
int n,s,m;
int vis[MAXN][MAXN][MAXN];
queue<pair<pair<int,int>, int > >q;///用pair代替结构体
void init()
{
    M(vis,0);
    while(!q.empty()) q.pop();
}
int bfs(int x,int y,int z)
{
    vis[x][y][z] = 1;
    q.push(make_pair(make_pair(x,y),z));
    while(!q.empty())
    {
        int x1 = q.front().first.first;
        int y1 = q.front().first.second;
        int z1 = q.front().second;
        if((y1==z1&&x1==0&&y1!=0)||(y1==x1&&z1==0&&y1!=0)||(x1==z1&&y1==0&&x1!=0))///任意两个容器相等,剩下一个容器的容量为0
        {
            return vis[x1][y1][z1] - 1;
        }
        q.pop();

        /*
        总共有六种倒可乐的情况,分别枚举即可
        1->2
        1->3
        2->1
        2->3
        3->1
        3->2
        */
        if(y1+x1<n)///1->2
        {
            if(vis[0][y1+x1][z1]==0)
            {
                vis[0][y1+x1][z1] = vis[x1][y1][z1] +1;
                q.push(make_pair(make_pair(0,y1+x1),z1));
            }
        }
        else
        {
            if(vis[x1+y1-n][n][z1]==0)
            {
                vis[x1+y1-n][n][z1] = vis[x1][y1][z1] +1;
                q.push(make_pair(make_pair(x1+y1-n,n),z1));
            }
        }
        if(x1+z1<m)///1->3
        {
            if(vis[0][y1][x1+z1]==0)
            {
                vis[0][y1][x1+z1] = vis[x1][y1][z1] +1;
                q.push(make_pair(make_pair(0,y1),x1+z1));
            }
        }
        else
        {
            if(vis[x1+z1-m][y1][m]==0)
            {
                vis[x1+z1-m][y1][m] = vis[x1][y1][z1] +1;
                q.push(make_pair(make_pair(x1+z1-m,y1),m));
            }
        }

        if(vis[y1+x1][0][z1]==0)///2->1
        {
            vis[y1+x1][0][z1] = vis[x1][y1][z1] +1;
            q.push(make_pair(make_pair(y1+x1,0),z1));
        }




        if(y1+z1<m)///2->3
        {
            if(vis[x1][0][y1+z1]==0)
            {
                vis[x1][0][y1+z1] = vis[x1][y1][z1] +1;
                q.push(make_pair(make_pair(x1,0),z1+y1));
            }
        }
        else
        {
            if(vis[x1][y1+z1-m][m]==0)
            {
                vis[x1][y1+z1-m][m] = vis[x1][y1][z1] +1;
                q.push(make_pair(make_pair(x1,y1+z1-m),m));
            }
        }

        if(vis[z1+x1][y1][0]==0)///3->1
        {
            vis[z1+x1][y1][0] = vis[x1][y1][z1] +1;
            q.push(make_pair(make_pair(z1+x1,y1),0));
        }


        if(y1+z1<n)///3->2
        {
            if(vis[x1][z1+y1][0]==0)
            {
                vis[x1][z1+y1][0] = vis[x1][y1][z1] +1;
                q.push(make_pair(make_pair(x1,z1+y1),0));
            }
        }
        else
        {
            if(vis[x1][n][z1+y1-n]==0)
            {
                vis[x1][n][z1+y1-n] = vis[x1][y1][z1] +1;
                q.push(make_pair(make_pair(x1,n),z1+y1-n));
            }
        }

    }
    return -1;
}
int main()
{
    while(scanf("%d %d %d",&s,&n,&m)&&s&&n&&m)
    {
        init();
        if(s%2==1)///s必须是偶数
        {
            printf("NO\n");
            continue;
        }
        int ans = bfs(s,0,0);

        if(ans==-1)
        {
            printf("NO\n");
        }
        else
        {
            printf("%d\n",ans);
        }
    }
    return 0;
}
//4 1 3
//
//4 0 0
//
//3 1 0
//1 0 3


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值