您的位置:首页 > 其它

HDU-1495 非常可乐 BFS

2011-08-08 17:51 405 查看

非常可乐

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


[align=left]Problem Description[/align]


家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这
一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S
(S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0)
。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。

[align=left]Input[/align]

三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。

[align=left]Output[/align]

如果能平分的话请输出最少要倒的次数,否则输出"NO"。

[align=left]Sample Input[/align]

7 4 3
4 1 3
0 0 0

[align=left]Sample Output[/align]

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: