zoukankan      html  css  js  c++  java
  • HDU1495 非常可乐 BFS

    非常可乐

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


    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

       找了很久规律还是无果(其实肯定有的),还是暴力搜索吧,对于三个容器,用一个结构题存储三个状态,每次寻找到一个状态的时候,判定是否已经满足要求。在暴力的时候,我找了六个状态,不知道是否可以再减少状态量,这里对于有6个状态是没有必要的,那就是对于单前容器,不要一次进行两次倒置,即将其分给另外两个容器(如果可行的话),这样会大大增加代码量,其实这个状态能够在下一次的计算中能够暴力到。搜索时记得记忆化,不然会形成死循环。
      代码如下:
    #include <stdio.h>
    #include <math.h>
    #include <queue>
    #include <cstring>
    using namespace std;
    
    struct Node
    {
    	int s, n, m, ti;
    }info;
    
    int S, N, M, hash[105][105][105];
    
    inline bool legal( Node t )
    {
        int cnt= 0;
        if( t.s== S/ 2 )
        {
            cnt++;
        }
        if( t.n== S/ 2 )
        {
            cnt++;
        }
        if( t.m== S/ 2 )
        {
            cnt++;
        }
        if( cnt== 2 )
        {
            return true;
        }
        return false;
    }
    
    bool BFS( int &ans )
    {
    	queue< Node >q;
    	info.s= S, info.m= 0, info.n= 0, info.ti= 0;
    	hash[S][0][0]= 0;
    	q.push( info );
    	while( !q.empty() )
    	{
    		Node pos= q.front();
    		q.pop();
    		if( legal( pos ) )
    		{
    			ans= pos.ti;
    			return true; 
    		}
    		if( pos.s> 0 )
    		{
    			if( pos.n< N )
    			{
    				int temp= min( pos.s, N- pos.n );
    				info.s= pos.s- temp;
    				info.n= pos.n+ temp;
    				info.m= pos.m;
    				info.ti= pos.ti+ 1;
    				if( pos.ti+ 1< hash[info.s][info.n][info.m] )
    				{
    					hash[info.s][info.n][info.m]= pos.ti;
    					q.push( info );
    				}
    			}
    			if( pos.m< M )
    			{
    				int temp= min( pos.s, M- pos.m );
    				info.s= pos.s- temp;
    				info.m= pos.m+ temp;
    				info.n= pos.n;
    				info.ti= pos.ti+ 1;
    				if( pos.ti+ 1< hash[info.s][info.n][info.m] )
    				{
    					hash[info.s][info.n][info.m]= pos.ti;
    					q.push( info );
    				}
    			}
    		}
    		if( pos.n> 0 )
    		{
    			if( pos.s< S )
    			{
    				int temp= min( pos.n, S- pos.s );
    				info.s= pos.s+ temp;
    				info.n= pos.n- temp;
    				info.m= pos.m;
    				info.ti= pos.ti+ 1;
    				if( pos.ti+ 1< hash[info.s][info.n][info.m] )
    				{
    					hash[info.s][info.n][info.m]= pos.ti;
    					q.push( info );
    				}
    			}
    			if( pos.m< M )
    			{
    				int temp= min( pos.n, M- pos.m );
    				info.n= pos.n- temp;
    				info.m= pos.m+ temp;
    				info.s= pos.s;
    				info.ti= pos.ti+ 1;
    				if( pos.ti+ 1< hash[info.s][info.n][info.m] )
    				{
    					hash[info.s][info.n][info.m]= pos.ti;
    					q.push( info );
    				}
    			}
    		}
    		if( pos.m> 0 )
    		{
    			if( pos.s< S )
    			{
    				int temp= min( pos.m, S- pos.s );
    				info.s= pos.s+ temp;
    				info.m= pos.m- temp;
    				info.n= pos.n;
    				info.ti= pos.ti+ 1;
    				if( pos.ti+ 1< hash[info.s][info.n][info.m] )
    				{
    					hash[info.s][info.n][info.m]= pos.ti;
    					q.push( info );
    				}
    			}
    			if( pos.n< N )
    			{
    				int temp= min( pos.m, N- pos.n );
    				info.m= pos.m- temp;
    				info.n= pos.n+ temp;
    				info.s= pos.s;
    				info.ti= pos.ti+ 1;
    				if( pos.ti+ 1< hash[info.s][info.n][info.m] )
    				{
    					hash[info.s][info.n][info.m]= pos.ti;
    					q.push( info );
    				}
    			}
    		}
    	}
    	return false;
    }
    
    int main()
    {
    	while( scanf( "%d %d %d", &S, &N, &M ), S| N| M )
    	{
    		if( S& 1 )
    		{
    			printf( "NO\n" );
    			continue;
    		}
    		int ans;
    		memset( hash, 0x7f, sizeof( hash ) ); 
    		if( BFS( ans ) )
    		{
    		    printf( "%d\n", ans );
    		}
    		else
    		{
    		    puts( "NO" );
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    ubuntu9.04 解决关机beep声音
    『转』饯行:理想主义终结年代的七种兵器
    尼康数码单反DX Nikkor镜头介绍
    Nikkor镜头介绍
    [转]IDL中全局变量的处理
    APSC画幅
    开心时刻1
    C# 相对路径
    使用C#语言,从Excel2007中读取数据,并显示到Form中的DataGridView。
    C# 讀取Excel、xlsx文件Excel2007
  • 原文地址:https://www.cnblogs.com/Lyush/p/2131191.html
Copyright © 2011-2022 走看看