三个水杯
时间限制:
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
- 来源
- 经典题目
- 上传者
- hzyqazasdf
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> using namespace std; #define inf 0x3f3f3f3f int v[5],ea,eb,ec; bool vis[100][100][100]; struct node { int s[5],step; }now,net; void bfs() { memset(vis,false,sizeof(vis)); queue<node>q; now.s[0]=v[0],now.s[1]=now.s[2]=now.step=0; vis[v[0]][0][0]=true; q.push(now); while(!q.empty()) { now=q.front(); q.pop(); if(now.s[0]==ea&&now.s[1]==eb&&now.s[2]==ec) { printf("%d\n",now.step); return ; } for(int i=0;i<3;i++) { for(int j=0;j<3;j++) { if(i!=j) { net=now; if(net.s[i]+net.s[j]<=v[j]) { net.s[j]+=net.s[i]; net.s[i]=0; } else { net.s[i]-=v[j]-net.s[j]; net.s[j]=v[j]; } if(!vis[net.s[0]][net.s[1]][net.s[2]]) { net.step++; vis[net.s[0]][net.s[1]][net.s[2]]=true; q.push(net); } } } } } printf("-1\n"); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d%d%d%d%d",&v[0],&v[1],&v[2],&ea,&eb,&ec); bfs(); } }