非常可乐
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
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
BFS涉及的范围非常广,这种题目也依然是暴利广搜一下就出来了,不过要想好一个问题,就是我们平时用BFS写迷宫题目时候那个next在这是怎样得出来的呢?这肯定不是坐标的变换,第二就是当时那个vst,防止你重复去判断一个点,在这道题又要怎么去定义这个vst呢?
我的思路十分简单粗暴,也不管那么多了,vst直接开一个三维数组来代替,大小为105*105*105,一开始初始化为0,如果出现一种新情况,就把vst[i][j][k]=1。然后就是他这个分配,我是分成了六种情况,s分给n,s分给m,n分给s,n分给m,m分给s,m分给n。这就可以得到next了,不像迷宫那些那么方便,这六种情况都要自己手敲出来,没有循环可言。。。
代码如下:
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define swap(a,b) {int c=a;a=b;b=c;}
const int maxn=105;
bool vst[maxn][maxn][maxn],flag;
int s,n,m;
struct State
{
int x,y,z;
int Step_Counter;
}t;
bool Check_State(State st)
{
if(st.x>=0 && st.x <=s && st.y>=0 && st.y <=n && st.z>=0 && st.z <=m && !vst[st.x][st.y][st.z])
return 1;
else
return 0;
}
void bfs(State st)
{
int tmp;
queue <State> q;
State now,next;
st.Step_Counter=0;
q.push(st);
vst[st.x][st.y][st.z]=1;
while(!q.empty())
{
now=q.front();
if(now.x==now.z&&now.y==0)
{
printf("%d\n",now.Step_Counter);
flag=1;
return;
}
next.Step_Counter=now.Step_Counter+1;
if(now.x!=0)//从x分配下去
{
//************************
tmp=now.x-(n-now.y);//x分配给y
if(tmp<0)//如果x全部分配给y y却仍未满
{
next.x=0;//只把能分配的分配
next.y=now.y+now.x;//直接补上x
}
else
{
next.x=tmp;
next.y=now.y+(n-now.y);
}
next.z=now.z;
if(Check_State(next))
{
q.push(next);
vst[next.x][next.y][next.z]=1;
}
//*************************//x分配给z
tmp=now.x-(m-now.z);
if(tmp<0)
{
next.x=0;
next.z=now.z+now.x;
}
else
{
next.x=tmp;
next.z=now.z+(m-now.z);
}
next.y=now.y;
if(Check_State(next))
{
q.push(next);
vst[next.x][next.y][next.z]=1;
}
}
if(now.y!=0)//从y分配下去
{
//*******************************
tmp=now.y-(s-now.x);//y分配给x
if(tmp<0)
{
next.y=0;
next.x=now.x+now.y;
}
else
{
next.y=tmp;
next.x=now.x+(s-now.x);
}
next.z=now.z;
if(Check_State(next))
{
q.push(next);
vst[next.x][next.y][next.z]=1;
}
//*******************************
tmp=now.y-(m-now.z);//y分配给z
if(tmp<0)
{
next.y=0;
next.z=now.z+now.y;
}
else
{
next.y=tmp;
next.z=now.z+(m-now.z);
}
next.x=now.x;
if(Check_State(next))
{
q.push(next);
vst[next.x][next.y][next.z]=1;
}
}
if(now.z!=0)//从z分配下去
{
//************************
tmp=now.z-(s-now.x);//z分配给x
if(tmp<0)
{
next.z=0;
next.x=now.x+now.z;
}
else
{
next.z=tmp;
next.x=now.x+(s-now.x);
}
next.y=now.y;
if(Check_State(next))
{
q.push(next);
vst[next.x][next.y][next.z]=1;
}
//**************************
tmp=now.z-(n-now.y);//z分配给y
if(tmp<0)
{
next.z=0;
next.y=now.y+now.z;
}
else
{
next.z=tmp;
next.y=now.y+(n-now.y);
}
next.x=now.x;
if(Check_State(next))
{
q.push(next);
vst[next.x][next.y][next.z]=1;
}
}
q.pop();
}
return;
}
int main()
{
while(scanf("%d%d%d",&s,&n,&m)!=EOF)
{
if(n+m+s==0)
break;
if(n>m)
swap(n,m);
memset(vst,0,sizeof(vst));
t.x=s;
t.y=0;
t.z=0;
if(s%2!=0)
{
printf("NO\n");
continue;
}
flag=0;
bfs(t);
if(flag==0)
printf("NO\n");
}
}