三个水杯

来源:互联网 发布:网络推广软件服务商 编辑:程序博客网 时间:2024/04/27 07:56

描述

给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。 

输入

第一行一个整数N(0<N<50)表示N组测试数据接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态

输出

每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1

样例输入

26 3 14 1 19 3 27 1 1

样例输出

3

-1

http://acm.nyist.net/JudgeOnline/problem.php?pid=21

六种状态0->1,1->0,1->2,2->1,2->3,3->2

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;int e1,e2,e3;struct node{int step;int v[3];};int cap[4];bool vis[105][105][105];void pour(int dest,int sour,node& t){int water=cap[dest]-t.v[dest];if(t.v[sour]<=water){t.v[dest]+=t.v[sour];t.v[sour]=0;}else {t.v[dest]+=water;t.v[sour]-=water;}}int bfs(){node s;s.v[0]=cap[0];s.v[1]=0;s.v[2]=0;s.step=0;vis[cap[0]][0][0]=true;queue<node>q;q.push(s);while(!q.empty()){node tmp=q.front();q.pop();if(tmp.v[0]==e1&&tmp.v[1]==e2&&tmp.v[2]==e3)return tmp.step;for(int i=0;i<3;i++){for(int j=1;j<3;j++){int k=(i+j)%3;//模拟三种状态if(tmp.v[i]==0||tmp.v[k]>=cap[k])continue;node x=tmp;pour(k,i,x);//cout<<x.v[0]<<x.v[1]<<x.v[2]<<endl;x.step=tmp.step+1;if(!vis[x.v[0]][x.v[1]][x.v[2]]){vis[x.v[0]][x.v[1]][x.v[2]]=true;q.push(x);}}}} return -1;}int main(){int ca;scanf("%d",&ca);while(ca--){for(int i=0;i<3;i++){scanf("%d",&cap[i]);}scanf("%d%d%d",&e1,&e2,&e3);if(e1==cap[0]&&cap[1]==0&&cap[2]==0){printf("0\n");continue;}memset(vis,false,sizeof(vis));int res=bfs();printf("%d\n",res);}return 0;} 


0 0