非常可乐
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是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"。
分析:
首先如果S是奇数肯定不能平分。
杯子是没有刻度的,所以杯子每一次倒水只有两种可能:
①把水全部倒给另一个杯子(如果另一个杯子装得下)
② 把另一个杯子倒满(如果另一个杯子装不下)
而每次执行倒水有六种可能,即1杯向2杯倒水,1杯向3杯倒水,2向1,2向3,3向1,3向2倒水。相当于六个方向的广搜。
AC代码:
其实我写得有些繁琐了。
S,N,M意义同题目,用s,n,m来记录三个杯子目前各有多少可乐。但这样写其实麻烦了好多,完全可以用一个数组coke[3]来代替,码量会少很多。
#include<string.h>
#include<queue>
#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
using namespace std;
int S,N,M;
typedef struct{
int s,n,m; //表示三个杯子各含多少可乐
int step;
}node;
node vis[10000];
int cnt=0;
int bfs(node start){
vis[cnt++]=start;
queue<node>q;
q.push(start);
while(!q.empty()){
node temp=q.front();
q.pop();
if(temp.m==S/2||temp.n==S/2||temp.s==S/2){//搜索终止条件
int t=0;
if(temp.m==S/2) t++;
if(temp.n==S/2) t++;
if(temp.s==S/2) t++;
if(t==2)
return temp.step;
else //把剩下两杯还需要一步
return temp.step+1;
}
for(int i=1;i<=6;i++){
node new_node=temp;
new_node.step++;
int pour;
if(i==1){
pour=min(N-temp.n,temp.s);/*能倒多少可乐,由当前杯子的剩余可乐和另一个杯子能装下的可乐共同决定,取二者的最小值*/
new_node.s-=pour;
new_node.n+=pour;
}
if(i==2) {
pour=min(M-temp.m,temp.s);
new_node.s-=pour;
new_node.m+=pour;
}
if(i==3) {
pour=min(S-temp.s,temp.n);
new_node.n-=pour;
new_node.s+=pour;
}
if(i==4) {
pour=min(M-temp.m,temp.n);
new_node.n-=pour;
new_node.m+=pour;
}
if(i==5) {
pour=min(S-temp.s,temp.m);
new_node.m-=pour;
new_node.s+=pour;
}
if(i==6) {
pour=min(N-temp.n,temp.m);
new_node.m-=pour;
new_node.n+=pour;
}
int flag=0;
for(int j=0;j<cnt;j++){
if(vis[j].m==new_node.m&&vis[j].n==new_node.n&&vis[j].s==new_node.s){
flag=1;
break;
}
}
if(!flag&&pour){
q.push(new_node);
vis[cnt++]=new_node;
}
}
}
return -1;
}
int main()
{
while(~scanf("%d%d%d",&S,&N,&M)&&S&&N&&M){
memset(vis,0,sizeof(vis));
cnt=0;
if(S%2){
printf("NO\n");
continue;
}
node start;
start.s=S;
start.m=0;
start.n=0;
start.step=0;
int ans=bfs(start);
if(ans!=-1){
printf("%d\n",ans);
}
else
printf("NO\n");
}
return 0;
}
测试数据:
4 1 3
3
3 2 1
NO
6 2 4
NO
4 2 2
1
13 6 7
NO
14 7 7
1
14 6 8
NO
14 5 9
13
100 42 58
49
100 82 18
49
26 12 14
NO
100 11 89
99
50 13 37
49
50 38 12
NO
50 15 35
9