yyf倒水
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 0 Accepted Submission(s): 0
Problem Description
yyf和他女朋友到一家饭店吃饭,饭店里的服务员给yyf和女朋友每人一个杯子并把一个水壶放在了一边。女朋友想喝饮料,从饭店冰箱里拿来了一瓶“小茗同学”。倒满两个杯子后,yyf忍不住喝了一口,十分惬意。女朋友把两个杯子放在一起,认真地看了杯子里的水,向yyf问道,假设第一个杯子的容量是A升,第二个杯子的容量B升,两个杯子一开始都为空,现在有三个操作,1.FILL(i):将i杯子中的饮料倒满。2.EMPTY(i):将i杯子中的饮料全部倒出只剩空瓶子。3.POUR(i,j)将杯子i中的水倒到杯子j中,若杯子 j 满了或者杯子i已经为空了则停止。如果你每次只能进行上面操作中的一种,你能在最少操作数内使其中一个杯子的饮料容量恰好为C吗?看着女朋友坚定的眼神,yyf陷入了深思,过了几秒,yyf发现自己已经能理论解决这个问题了,但是无奈没有电脑,所以向你求助,聪明的你,能帮助yyf回答这个问题吗?
Input
输入包含三个数A,B,C,三个数保证是整数且范围都是在[1,100]内,C<=max(A,B)
Output
如果能到达目标输出第一行包含一个整数k表示到达目标水量最少需要操作的步骤数。如果不能到达目标则输出“impossible”(没有双引号)。
Sample Input
3 5 4
3 100 64
Sample Output
Hint
【分析】
注意到数据非常小,所以简单bfs直接搜索(x,y)情况就可以了,对当前(x,y)有6种情况
1.倒满A杯
2.倒满B杯
3.倒空A杯
4.倒空B杯
5.将A杯倒入B杯
6.将B杯倒入A杯
跟最短路一样,中途最早搜到的点肯定是最优解,直接return结束搜索
【代码】
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
int A,B,C;
int vis[200][200],dis[200][200];
struct xx{
int a,b;
xx(int a,int b):a(a),b(b){}
};
int bfs()
{
queue<xx> q;
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
dis[0][0]=0;
vis[0][0]=1;
q.push(xx(0,0));
while(!q.empty())
{
xx x=q.front();
q.pop();
for(int i=1;i<=6;i++)
{
int X,Y;
if(i==1){X=A;Y=x.b;}
if(i==2){X=x.a; Y=B;}
if(i==3){X=0; Y=x.b;}
if(i==4){X=x.a; Y=0;}
if(i==5){X=x.a+x.b>=B?x.a+x.b-B:0;Y=x.a+x.b>=B?B:x.a+x.b;}
if(i==6){X=x.a+x.b>=A?A:x.a+x.b;Y=x.a+x.b>=A?x.a+x.b-A:0;}
if(!vis[X][Y])
{
vis[X][Y]=1;
dis[X][Y]=dis[x.a][x.b]+1;
if(X==C||Y==C) return dis[X][Y];
q.push(xx(X,Y));
}
}
}
return -1;
}
int main()
{
while (~scanf("%d%d%d",&A,&B,&C))
{
int ans=bfs();
if (ans!=-1) printf("%d\n",ans);
else puts("impossible");
}
return 0;
}