Time Limit: 2000/1000 MS (java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 12643 Accepted Submission(s): 5066
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是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
题解:观察这道题目,发现它的初始状态就是m=0,n=0,s=s.(n是大杯里的量,m是小杯里的量,s是可乐瓶里的量),如果想要它们平分,最后一定是n=s/2,s=s/2,m=0。就是说大杯子和可乐瓶里的量各是总量的一半就表示能平分。我们只要朝着这个方向靠拢就可以了,而又要求最小的步数,有一个初始的状态又有终点状态,还要求最小步数,可以想到用bfs求解。乍一看还真跟bfs扯不上关系,仔细分析它每一步就6个方向(s->n,s->m,m->n,n->m,n->s,m->s),相当于bfs迷宫求解中的方向。
对这6个方向用bfs最后在n=s/2,s=s/2的时候结束,就可以完成了。这题只要想清楚这些,具体这个水怎么倒的就交给电脑去完成吧,我们只要坐等答案就好了。
另外当可乐总容量为奇数的时候怎么倒都不可能平分所以直接排除就行了。
AC代码:
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
const int N=105;
struct node
{
int n,m,s,t;
}now;
bool vis[N][N];
int n,m,s;
int bfs()
{
now.n=0,now.m=0,now.s=s,now.t=0;
memset(vis,0,sizeof(vis));
queue<node>q;
vis[n][m]=1;
q.push(now);
while(!q.empty())
{
node cur=q.front(),v;
q.pop();
if(cur.s==s/2&&cur.n==s/2)
return cur.t;
if(cur.s&&cur.n!=n)//s->n
{
int c=n-cur.n;
if(cur.s>=c)
{
v.n=n;
v.s=cur.s-c;
}
else
{
v.s=0;
v.n=cur.n+cur.s;
}
v.m=cur.m;
v.t=cur.t+1;
if(!vis[v.n][v.m])
{
q.push(v);
vis[v.n][v.m]=1;
}
}
if(cur.s&&cur.m!=m)//s->m
{
int c=m-cur.m;
if(cur.s>=c)
{
v.m=m;
v.s=cur.s-c;
}
else
{
v.s=0;
v.m=cur.m+cur.s;
}
v.n=cur.n;
v.t=cur.t+1;
if(!vis[v.n][v.m])
{
q.push(v);
vis[v.n][v.m]=1;
}
}
if(cur.n&&cur.s!=s)//n->s
{
int c=s-cur.s;
if(cur.n>=c)
{
v.s=s;
v.n=cur.n-c;
}
else
{
v.n=0;
v.s=cur.s+cur.n;
}
v.m=cur.m;
v.t=cur.t+1;
if(!vis[v.n][v.m])
{
q.push(v);
vis[v.n][v.m]=1;
}
}
if(cur.m&&cur.s!=s)//m->s
{
int c=s-cur.s;
if(cur.m>=c)
{
v.s=s;
v.m=cur.m-c;
}
else
{
v.m=0;
v.s=cur.s+cur.m;
}
v.n=cur.n;
v.t=cur.t+1;
if(!vis[v.n][v.m])
{
q.push(v);
vis[v.n][v.m]=1;
}
}
if(cur.n&&cur.m!=m)//n->m
{
int c=m-cur.m;
if(cur.n>=c)
{
v.m=m;
v.n=cur.n-c;
}
else
{
v.n=0;
v.m=cur.m+cur.n;
}
v.s=cur.s;
v.t=cur.t+1;
if(!vis[v.n][v.m])
{
q.push(v);
vis[v.n][v.m]=1;
}
}
if(cur.m&&cur.n!=n)//m->n
{
int c=n-cur.n;
if(cur.m>=c)
{
v.n=n;
v.m=cur.m-c;
}
else
{
v.m=0;
v.n=cur.n+cur.m;
}
v.s=cur.s;
v.t=cur.t+1;
if(!vis[v.n][v.m])
{
q.push(v);
vis[v.n][v.m]=1;
}
}
}
return 0;
}
int main()
{
while(cin>>s>>n>>m)
{
int t;
if(s==0&&n==0&&m==0)
break;
if(s%2!=0)
{
cout<<"NO"<<endl;
continue;
}
if(n<m)
{
t=n;
n=m;
m=t;
}
int ans=bfs();
if(ans)
cout<<ans<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
新闻热点
疑难解答