三个水杯
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
-
输入
-
第一行一个整数N(0<N<50)表示N组测试数据
接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态
输出
- 每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1 样例输入
-
2 6 3 1 4 1 1 9 3 2 7 1 1
样例输出
-
3 -1
-
-
tips:每个节点的下一个状态最多有六种,注意不能定量倒水,只能倒满或者被倒空。
-
#include<iostream> #include<cstring> #include<queue> using namespace std; int v1,v2,v3; int ex,ey,ez; int book[101][101][101]; struct node{ int a,b,c,step; }; void bfs() { queue<node>q; book[v1][0][0]=1; q.push(node{v1,0,0,0}); while(!q.empty()) { node tt=q.front();q.pop(); int x=tt.a,y=tt.b,z=tt.c; if(x==ex&&y==ey&&z==ez){cout<<tt.step<<endl;return;} int nx=x,ny=y,nz=z; if(x&&y<v2) //1-->2 { if(x>v2-y)nx=x-(v2-y),ny=v2; else nx=0,ny=y+x; nz=z; if(!book[nx][ny][nz])book[nx][ny][nz]=1,q.push(node{nx,ny,nz,tt.step+1}); } if(x&&z<v3) //1-->3 { if(x>v3-z)nx=x-(v3-z),nz=v3; else nx=0,nz=z+x; ny=y; if(!book[nx][ny][nz])book[nx][ny][nz]=1,q.push(node{nx,ny,nz,tt.step+1}); } if(y&&x<v1) //2-->1 { if(y>v1-x)ny=y-(v1-x),nx=v1; else ny=0,nx=x+y; nz=z; if(!book[nx][ny][nz])book[nx][ny][nz]=1,q.push(node{nx,ny,nz,tt.step+1}); } if(y&&z<v3) //2-->3 { if(y>v3-z)ny=y-(v3-z),nz=v3; else ny=0,nz=z+y; nx=x; if(!book[nx][ny][nz])book[nx][ny][nz]=1,q.push(node{nx,ny,nz,tt.step+1}); } if(z&&x<v1) //3-->1 { if(z>v1-x)nz=z-(v1-x),nx=v1; else nz=0,nx=x+z; ny=y; if(!book[nx][ny][nz])book[nx][ny][nz]=1,q.push(node{nx,ny,nz,tt.step+1}); } if(z&&y<v2) //3-->2 { if(z>v2-y)nz=z-(v2-y),ny=v2; else nz=0,ny=y+z; nx=x; if(!book[nx][ny][nz])book[nx][ny][nz]=1,q.push(node{nx,ny,nz,tt.step+1}); } } cout<<-1<<endl; } int main() { int t;cin>>t; while(t--) { memset(book,0,sizeof(book)); cin>>v1>>v2>>v3>>ex>>ey>>ez; bfs(); } return 0; }
-
第一行一个整数N(0<N<50)表示N组测试数据