思路:BFS。倒水共有6中情况既(A->B,A->C),(B->A,B->C),(C->A,C->B),我们可以写一个双重循环来模拟这六种情况(当然你也可以把这六种情况一一写出来)。当 i -> j,i给j倒水的时候有两种情况,① i 可以把 j 给装满 ② i 装不满 j 。两种情况不一样记得判断一下即可。标记数组开为3维,每一个维度表示一个杯子。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
using namespace std;
struct Node
{
int cup[3];
int steps;
};
int S[3],E[3],V[105][105][105];
int bfs()//倒水共有6中情况既(A->B,A->C),(B->A,B->C),(C->A,C->B)
{
Node Start;
Start.cup[0]=S[0];Start.cup[1]=0;Start.cup[2]=0;Start.steps=0;
V[Start.cup[0]][Start.cup[1]][Start.cup[2]]=1;
queue<Node>q;
q.push(Start);
while(!q.empty())
{
Start=q.front();
q.pop();
if(Start.cup[0]==E[0]&&Start.cup[1]==E[1]&&Start.cup[2]==E[2])//结束条件
{
return Start.steps;
}
//i->j
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(i!=j) //不是同一个水杯
{
int water=S[j]-Start.cup[j];//j这个杯子还能装多少水
if(Start.cup[i]<water)//i倒不满j
{
water=Start.cup[i];
}
Node D=Start;
D.cup[i]=Start.cup[i]-water; D.cup[j]=Start.cup[j]+water; D.steps=Start.steps+1;
if(V[D.cup[0]][D.cup[1]][D.cup[2]]==0)//状态没有出现过
{
V[D.cup[0]][D.cup[1]][D.cup[2]]=1;
q.push(D);
}
}
}
}
}
return -1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(V,0,sizeof(V));
scanf("%d%d%d%d%d%d",&S[0],&S[1],&S[2],&E[0],&E[1],&E[2]);
if((E[0]+E[1]+E[2])!=S[0]) printf("-1\n");
else printf("%d\n",bfs());
}
return 0;
}