HDU-1495 非常可乐 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
4 1 3
0 0 0
Sample Output
NO
3
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; }