题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495
题目大意:一瓶S的可乐,两个容量分别为N和M的杯子,三者能够相互倾倒可乐,并且S=M+N,问是否能得到相同的两份可乐。如果能的话就计算最少的操作步数。
题解:就是有六种操作,然后就用常规bfs来做。每种操作额外考虑一下能否倒完就好了。
FEELING:debug了很久,本来昨天做了一道类似的而且还比这个难,但是这个还是做了一个多小时,debug了贼久,然后最后发现是有个最后一种操作的字母有地方写错了,天呐,也真的是……不然另一道题就开出来了,室友等我回去还是要走了,呜呜呜,伤心……
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <math.h>
#include <string.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <map>
#define INF 0x3f3f3f3f
const int MAX=0x3f3f3f3f;
using namespace std;
typedef long long ll;
int S,N,M;
struct node{
int s,n,m;//当前状态
int step;//步数
};
int mp[105][105][105];
int bfs(int es,int en,int em)
{
memset(mp,false,sizeof(mp));
node temp;
temp.s=es;
temp.n=en;
temp.m=em;
temp.step=0;
queue<node>q;
q.push(temp);
mp[q.front().s][q.front().n][q.front().m]=1;
while(!q.empty())
{
for(int i=0;i<6;i++)
{
if(i==0)//S->N
{
//如果能倒完
if(q.front().s<=N-q.front().n)
{
temp.n=q.front().n+q.front().s;
temp.s=0;
temp.m=q.front().m;
}
//如果不能倒完
else if(q.front().s>N-q.front().n)
{
temp.s=q.front().s-(N-q.front().n);
temp.n=N;
temp.m=q.front().m;
}
}
else if(i==1)//S->M
{
//如果能倒完
if(q.front().s<=M-q.front().m)
{
temp.m=q.front().m+q.front().s;
temp.s=0;
temp.n=q.front().n;
}
//如果不能倒完
else if(q.front().s>M-q.front().m)
{
temp.s=q.front().s-(M-q.front().m);
temp.m=M;
temp.n=q.front().n;
}
}
else if(i==2)//N->S
{
//如果能倒完
if(q.front().n<=S-q.front().s)
{
temp.s=q.front().n+q.front().s;
temp.n=0;
temp.m=q.front().m;
}
//如果不能倒完
else if(q.front().n>S-q.front().s)
{
temp.n=q.front().n-(S-q.front().s);
temp.s=S;
temp.m=q.front().m;
}
}
else if(i==3)//N->M
{
//如果能倒完
if(q.front().n<=M-q.front().m)
{
temp.m=q.front().n+q.front().m;
temp.n=0;
temp.s=q.front().s;
}
//如果不能倒完
else if(q.front().n>M-q.front().m)
{
temp.n=q.front().n-(M-q.front().m);
temp.m=M;
temp.s=q.front().s;
}
}
else if(i==4)//M->S
{
//如果能倒完
if(q.front().m<=S-q.front().s)
{
temp.s=q.front().m+q.front().s;
temp.m=0;
temp.n=q.front().n;
}
//如果不能倒完
else if(q.front().m>S-q.front().s)
{
temp.m=q.front().m-(S-q.front().s);
temp.s=S;
temp.n=q.front().n;
}
}
else if(i==5)//M->N
{
//如果能倒完
if(q.front().m<=N-q.front().n)
{
temp.n=q.front().n+q.front().m;
temp.m=0;
temp.s=q.front().s;
}
//如果不能倒完
else if(q.front().m>N-q.front().n)
{
temp.m=q.front().m-(N-q.front().n);
temp.n=N;
temp.s=q.front().s;
}
}
if(mp[temp.s][temp.n][temp.m]==1)
continue;
temp.step=q.front().step+1;
q.push(temp);
mp[temp.s][temp.n][temp.m]=1;
if((temp.s==temp.n&&temp.m==0)||(temp.s==temp.m&&temp.n==0)||(temp.m==temp.n&&temp.s==0))
return temp.step;
}
q.pop();
}
return 0;
}
int main()
{
while(~scanf("%d%d%d",&S,&N,&M)&&(S||N||M))
{
int ans=bfs(S,0,0);
if(ans==0)
printf("NO\n");
else
printf("%d\n",ans);
}
return 0;
}