首页 > 代码库 > HDU 1495 非常可乐(bfs)

HDU 1495 非常可乐(bfs)

非常可乐

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


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   |   We have carefully selected several similar problems for you:  1175 1253 1072 1372 1180 
 
题解:
分6种情况:s->n,s->m,n->s,n->m,m->s,m->n.
每种请款又分倒满和倒不满。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<map>

#define N 100010
#define Mod 10000007
#define lson l,mid,idx<<1
#define rson mid+1,r,idx<<1|1
#define lc idx<<1
#define rc idx<<1|1
const double EPS = 1e-11;
const double PI = acos ( -1.0 );
const double E = 2.718281828;
typedef long long ll;

const int INF = 1000010;

using namespace std;

int s,n,m;
bool vis[111][111][111],flag;
struct node
{
    int s,n,m;
    int num;
};

queue<node>que;

void bfs()
{
    while(que.size())
        que.pop();
    memset(vis,0,sizeof vis);
    node a,t;
    a.s=s,a.n=0,a.m=0,a.num=0;
    que.push(a);
    vis[s][0][0]=1;
    while(que.size())
    {
        a=que.front();
        que.pop();
        if(a.s==a.n&&a.m==0||(a.s==0&&a.n==a.m)||(a.n==0&&a.s==a.m))
        {
            flag=0;
            cout<<a.num<<endl;
            return;
        }
        if(a.s>0)//s->n,s->m
        {
            if(a.n<n)//s->n
            {
                int tt=n-a.n;
                if(a.s>tt)//n可以倒满
                {
                    t.s=a.s-tt;
                    t.n=n;
                    t.m=a.m;
                }
                else//不可以倒满
                {
                    t.s=0;
                    t.n=a.s+a.n;
                    t.m=a.m;
                }
                if(!vis[t.s][t.n][t.m])
                {
                    t.num=a.num+1;
                    que.push(t);
                    vis[t.s][t.n][t.m]=1;
                }
            }
            if(a.m<m)
            {
                int tt=m-a.m;
                if(a.s>tt)
                {
                    t.s=a.s-tt;
                    t.n=a.n;
                    t.m=m;
                }
                else
                {
                    t.s=0;
                    t.n=a.n;
                    t.m=a.m+a.s;
                }
                if(!vis[t.s][t.n][t.m])
                {
                    t.num=a.num+1;
                    que.push(t);
                    vis[t.s][t.n][t.m]=1;
                }
            }
        }
        if(a.n>0)
        {
            if(a.s<s)
            {
                int tt=s-a.s;
                if(a.n>tt)
                {
                    t.n=a.n-tt;
                    t.m=a.m;
                    t.s=s;
                }
                else
                {
                    t.n=0;
                    t.m=a.m;
                    t.s=a.s+a.n;
                }
                if(!vis[t.s][t.n][t.m])
                {
                    t.num=a.num+1;
                    que.push(t);
                    vis[t.s][t.n][t.m]=1;
                }
            }
            if(a.m<m)
            {
                int tt=m-a.m;
                if(a.n>tt)
                {
                    t.n=a.n-tt;
                    t.m=m;
                    t.s=a.s;
                }
                else
                {
                    t.n=0;
                    t.m=a.m+a.n;
                    t.s=a.s;
                }
                if(!vis[t.s][t.n][t.m])
                {
                    t.num=a.num+1;
                    que.push(t);
                    vis[t.s][t.n][t.m]=1;
                }
            }
        }
        if(a.m>0)
        {
            if(a.s<s)
            {
                int tt=s-a.s;
                if(a.m>tt)
                {
                    t.n=a.n;
                    t.m=a.m-tt;
                    t.s=s;
                }
                else
                {
                    t.n=a.n;
                    t.m=0;
                    t.s=a.s+a.m;
                }
                if(!vis[t.s][t.n][t.m])
                {
                    t.num=a.num+1;
                    que.push(t);
                    vis[t.s][t.n][t.m]=1;
                }
            }
            if(a.n<n)
            {
                int tt=n-a.n;
                if(a.m>tt)
                {
                    t.n=n;
                    t.m=a.m-tt;
                    t.s=a.s;
                }
                else
                {
                    t.n=a.n+a.m;
                    t.m=0;
                    t.s=a.s;
                }
                if(!vis[t.s][t.n][t.m])
                {
                    t.num=a.num+1;
                    que.push(t);
                    vis[t.s][t.n][t.m]=1;
                }
            }
        }
    }
}
int main()
{
    while(cin>>s>>n>>m&&(s+n+m))
    {
        if(s%2)//奇数不能平分
        {
            cout<<"NO\n";
            continue;
        }
        flag=1;
        bfs();
        if(flag)
            cout<<"NO"<<endl;
    }
    return 0;
}


HDU 1495 非常可乐(bfs)