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
具体思路
三个容器问是否能平分可乐,其实就是bfs的广搜题,每一个初始状态都有六种操作,即ntom,ntos,mton,mtos,stom,ston,每一个操作又有两种情况,一直是倒的杯子比被倒的剩余空间多,另一种就是少,就是一题大模拟bfs,代码有点长,一开始开个矩阵标记这三个容器状态值是否被使用过即可
#include<bits/stdc++.h>
using namespace std;
int bj[105][105][105];
int s,n,m,k;
queue<int>duis;
queue<int>duin;
queue<int>duim;
void bfs()
{
while (!duis.empty()&&!duin.empty()&&!duim.empty())
{
int ss=duis.front();
int nn=duin.front();
int mm=duim.front();
// printf("%d %d %d %d\n",ss,nn,mm,bj[ss][nn][mm]);
if ((ss==k&&nn==k)||(ss==k&&mm==k)||(mm==k&&nn==k))
{
printf("%d\n",bj[ss][nn][mm]);
return ;
}
if (bj[ss-(n-nn)][nn+(n-nn)][mm]==0&&ss-(n-nn)>=0&&nn+(n-nn)<=n)
{
bj[ss-(n-nn)][nn+(n-nn)][mm]=bj[ss][nn][mm]+1;
//printf("%d\n", bj[ss-(n-nn)][nn+(n-nn)][mm]);
duis.push(ss-(n-nn));
duin.push(nn+(n-nn));
duim.push(mm);
}
if (bj[ss-(m-mm)][nn][mm+(m-mm)]==0&&ss-(m-mm)>=0&&mm+(m-mm)<=m)
{
bj[ss-(m-mm)][nn][mm+(m-mm)]=bj[ss][nn][mm]+1;
duis.push(ss-(m-mm));
duin.push(nn);
duim.push(mm+(m-mm));
}
if (bj[ss+(s-ss)][nn-(s-ss)][mm]==0&&ss+(s-ss)<=s&&nn-(s-ss)>=0)
{
bj[ss+(s-ss)][nn-(s-ss)][mm]=bj[ss][nn][mm]+1;
duis.push(ss+(s-ss));
duin.push(nn-(s-ss));
duim.push(mm);
}
if (bj[ss][nn-(m-mm)][mm+(m-mm)]==0&&nn-(m-mm)>=0&&mm+(m-mm)<=m)
{
bj[ss][nn-(m-mm)][mm+(m-mm)]=bj[ss][nn][mm]+1;
duis.push(ss);
duin.push(nn-(m-mm));
duim.push(mm+(m-mm));
}
if (bj[ss+(s-ss)][nn][mm-(s-ss)]==0&&ss+(s-ss)<=s&&mm-(s-ss)>=0)
{
bj[ss+(s-ss)][nn][mm-(s-ss)]=bj[ss][nn][mm]+1;
duis.push(ss+(s-ss));
duin.push(nn);
duim.push(mm-(s-ss));
}
if (bj[ss][nn+(n-nn)][mm-(n-nn)]==0&&nn+(n-nn)<=n&&mm-(n-nn)>=0)
{
bj[ss][nn+(n-nn)][mm-(n-nn)]=bj[ss][nn][mm]+1;
duis.push(ss);
duin.push(nn+(n-nn));
duim.push(mm-(n-nn));
}
if (nn<=s-ss&&bj[ss+nn][0][mm]==0)
{
bj[ss+nn][0][mm]=bj[ss][nn][mm]+1;
//printf("%d\n", bj[ss-(n-nn)][nn+(n-nn)][mm]);
duis.push(ss+n);
duin.push(0);
duim.push(mm);
}
if (mm<=s-ss&&bj[ss+mm][nn][0]==0)
{
bj[ss+mm][nn][0]=bj[ss][nn][mm]+1;
//printf("%d\n", bj[ss-(n-nn)][nn+(n-nn)][mm]);
duis.push(ss+mm);
duin.push(nn);
duim.push(0);
}
if (ss<=n-nn&&bj[0][ss+nn][mm]==0)
{
bj[0][nn+ss][mm]=bj[ss][nn][mm]+1;
duis.push(0);
duin.push(nn+ss);
duim.push(mm);
}
if (mm<=n-nn&&bj[ss][nn+mm][0]==0)
{
bj[ss][nn+mm][0]=bj[ss][nn][mm]+1;
duis.push(ss);
duin.push(nn+mm);
duim.push(0);
}
if (ss<=m-mm&&bj[0][nn][mm+ss]==0)
{
bj[0][nn][mm+ss]=bj[ss][nn][mm]+1;
duis.push(0);
duin.push(nn);
duim.push(mm+ss);
}
if (nn<=m-mm&&bj[ss][0][mm+nn]==0)
{
bj[ss][0][mm+nn]=bj[ss][nn][mm]+1;
duis.push(ss);
duin.push(0);
duim.push(mm+nn);
}
duis.pop();
duin.pop();
duim.pop();
}
printf("NO\n");
return ;
}
int main()
{
while (scanf("%d %d %d",&s,&n,&m)&&s!=0&&n!=0&&m!=0)
{
memset(bj,0,sizeof(bj));
if (s%2==1)
{
printf("NO\n");
continue;
}else
{
while (!duis.empty()&&!duin.empty()&&!duim.empty())
{
duis.pop();
duin.pop();
duim.pop();
}
k=s/2;
bj[s][0][0]=0;
duis.push(s);
duin.push(0);
duim.push(0);
bfs();
}
}
return 0;
}