HDU 1495 非常可乐(最笨办法版)

5 篇文章 0 订阅

原题链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1495

题目大意:

思路:

3个杯子。有6种情况的道法。每种遍历就可以了
主要是比较复杂的原因是加法较多。
结构体只是为了方便一点。
退出时的判定比较坑。要两个相等的同时另一个等于0才满足条件

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

int S,N,M;
int NUMBER;
bool Can;
int vis[101][101][101];

struct Tri
{
    int s;
    int n;
    int m;
    int number;
};


bool IsOver( int s,int n,int m )
{
    if( (s == m && s != 0 && n == 0 )|| ( s == n && n != 0 && m==0 )|| ( m == n && m !=0 && s == 0 ) )
        return true;
    return false;
}

bool IsLeagal( int s,int n,int m )
{
    if( s < 0 || s > S || n < 0 || n > N || m < 0 || m > M )
        return false;
    return true;
}

void bfs()
{
    queue<Tri> Ways;
    memset( vis,0,sizeof( vis));

    vis[S][0][0] = 1;

    Tri Now,Next1,Next2,Next3,Next4,Next5,Next6;
    Now.s = S;
    Now.n = 0;
    Now.m = 0;
    Now.number  = 0;
    Ways.push ( Now );
    while( !Ways.empty ())
    {
        Now.s = Ways.front ().s ;
        Now.n = Ways.front ().n ;
        Now.m = Ways.front ().m ;
        Now.number = Ways.front ().number ;
        Ways.pop ();

        if( Can )
            return;
        /* 从第一个杯子到给第二个杯子 */
        if( Now.s > ( N - Now.n) )
        {   Next1.s = Now.s - ( N - Now.n);
            Next1.n = N;
            Next1.m = Now.m;
            Next1.number = Now.number + 1;}
        else 
        {   Next1.s = 0;
            Next1.n = Now.n + Now.s ;
            Next1.m = Now.m;
            Next1.number = Now.number + 1;}
        if( IsLeagal( Next1.s ,Next1.n ,Next1.m ) && !vis[Next1.s ][Next1.n ][Next1.m ])
        {
            vis[Next1.s ][Next1.n ][Next1.m ] = 1;
            if( IsOver( Next1.s ,Next1.n ,Next1.m ))
            {   Can = true;
                NUMBER = Next1.number ;
                return; }
            Ways.push ( Next1 );
        }

        /* 从第一个杯子到给第三个杯子 */
        if( Now.s > ( M - Now.m ) )
        {   Next2.s = Now.s - ( M - Now.m );
            Next2.n = Now.n;
            Next2.m = M;
            Next2.number = Now.number + 1;}
        else
        {   Next2.s = 0;
            Next2.n = Now.n;
            Next2.m = Now.s + Now.m;
            Next2.number = Now.number + 1;}
        if( IsLeagal( Next2.s ,Next2.n ,Next2.m ) && !vis[Next2.s ][Next2.n ][Next2.m ])
        {
            vis[Next2.s ][Next2.n ][Next2.m ] = 1;
            if( IsOver( Next2.s ,Next2.n,Next2.m ))
            {   Can = true;
                NUMBER =  Next2.number  ;
                return; }
            Ways.push ( Next2 );
        }

        /* 从第二个杯子到给第一个杯子 */
        if( Now.n > ( S - Now.s ) )
        {   Next3.s = S;
            Next3.n = Now.n - ( S - Now.s );
            Next3.m = Now.m;
            Next3.number = Now.number + 1;}
        else
        {   Next3.s = Now.s + Now.n ;
            Next3.n = 0;
            Next3.m = Now.m;
            Next3.number = Now.number + 1;}
        if( IsLeagal( Next3.s ,Next3.n ,Next3.m ) && !vis[Next3.s ][Next3.n ][Next3.m ])
        {
            vis[Next3.s ][Next3.n ][Next3.m ] = 1;
            if( IsOver( Next3.s ,Next3.n ,Next3.m ))
            {   Can = true;
                NUMBER = Next3.number ;
                return; }
            Ways.push ( Next3 );
        }

        /* 从第二个杯子到给第三个杯子 */
        if( Now.n > ( M - Now.m ))
        {   Next4.s = Now.s ;
            Next4.n = Now.n - ( M - Now.m );
            Next4.m = M;
            Next4.number = Now.number + 1;}
        else
        {   Next4.s = Now.s ;
            Next4.n = 0;
            Next4.m = Now.n + Now.m ;
            Next4.number = Now.number + 1;}
        if( IsLeagal( Next4.s ,Next4.n ,Next4.m ) && !vis[Next4.s ][Next4.n ][Next4.m ])
        {
            vis[Next4.s ][Next4.n ][Next4.m ] = 1;
            if( IsOver( Next4.s ,Next4.n ,Next4.m ))
            {   Can = true;
                NUMBER = Next4.number ;
                return; }
            Ways.push ( Next4 );
        }

        /* 从第三个杯子到给第一个杯子 */
        if( Now.m - ( S - Now.s ) )
        {   Next5.s = S;
            Next5.n = Now.n ;
            Next5.m = Now.m - ( S - Now.s );
            Next5.number = Now.number + 1;}
        else
        {   Next5.s = Now.s + Now.m ;
            Next5.n = Now.n ;
            Next5.m = 0;
            Next5.number = Now.number + 1;}
        if( IsLeagal( Next5.s ,Next5.n ,Next5.m ) && !vis[Next5.s ][Next5.n ][Next5.m ])
        {
            vis[Next5.s ][Next5.n ][Next5.m ] = 1;
            if( IsOver( Next5.s ,Next5.n ,Next5.m ))
            {   Can = true;
                NUMBER = Next5.number ;
                return; }
            Ways.push ( Next5 );
        }

        /* 从第三个杯子到给第二个杯子 */
        if( Now.m > ( N - Now.n ))
        {   Next6.s = Now.s;
            Next6.n = N;
            Next6.m = Now.m - ( N - Now.n );
            Next6.number = Now.number + 1;}
        else
        {   Next6.s = Now.s;
            Next6.n = Now.m + Now.n ;
            Next6.m = 0;
            Next6.number = Now.number + 1;}
        if( IsLeagal( Next6.s ,Next6.n ,Next6.m ) && !vis[Next6.s ][Next6.n ][Next6.m ])
        {
            vis[Next6.s ][Next6.n ][Next6.m ] = 1;
            if( IsOver( Next6.s ,Next6.n ,Next6.m ))
            {   Can = true;
                NUMBER = Next6.number ;
                return; }
            Ways.push ( Next6 );
        }

    }
}
int main()
{
    while( cin >> S >> N >> M )
    {
        if( S == 0 && N == 0 && M == 0 ) break;
        if( N > M )
        {
            int tmp;
            tmp = N;
            N =M;
            M = tmp;
        }
        if( S % 2 != 0 )
        {
            cout<<"NO"<<endl;
            continue;
        }
        Can = false;
        bfs();
        if( Can )
            cout<< NUMBER <<endl;   
        else 
            cout<<"NO"<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值