时间限制:
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
-
第一行一个整数N(0<N<50)表示N组测试数据
解题思路: 本题是一道搜索题目,较容易理解。使用宽搜,对每一种状态下的每一种情况进行搜索,然后进行记录,如果搜索到的和目标数据一样,由宽搜的性质即可知道其是最小的。
参考程序:
#include<iostream>
#include<algorithm>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
struct node{
int a,b,c,ceng;
node(){
a=b=c=ceng=0;
}
}b,e,cur,temp;
int v1,v2,v3;
queue<node> myqueue;
bool used[100][100][100];
int BFS(node b){
while (!myqueue.empty()) myqueue.pop();
memset(used,0,sizeof(used));
myqueue.push(b); used[b.a][b.b][b.c]=true;
myqueue.push(b);
while (!myqueue.empty()){
cur=myqueue.front();
if (cur.a==e.a&&cur.b==e.b&&cur.c==e.c)
return cur.ceng;
myqueue.pop();
if (cur.a>0&&cur.b<v2){ //v1->v2
temp=cur;
int tt=min(cur.a,v2-cur.b);
temp.a-=tt;
temp.b+=tt;
if (!used[temp.a][temp.b][temp.c]){
used[temp.a][temp.b][temp.c]=true;
temp.ceng++;
myqueue.push(temp);
}
}
if (cur.a>0&&cur.c<v3){ //v1->v3
temp=cur;
int tt=min(cur.a,v3-cur.c);
temp.a-=tt;
temp.c+=tt;
if (!used[temp.a][temp.b][temp.c]){
used[temp.a][temp.b][temp.c]=true;
temp.ceng++;
myqueue.push(temp);
}
}
if (cur.b>0&&cur.c<v3){ //v2->v3
temp=cur;
int tt=min(cur.b,v3-cur.c);
temp.b-=tt;
temp.c+=tt;
if (!used[temp.a][temp.b][temp.c]){
used[temp.a][temp.b][temp.c]=true;
temp.ceng++;
myqueue.push(temp);
}
}
if (cur.c>0&&cur.a<v1){ //v3->v1
temp=cur;
int tt=min(cur.c,v1-cur.a);
temp.c-=tt;
temp.a+=tt;
if (!used[temp.a][temp.b][temp.c]){
used[temp.a][temp.b][temp.c]=true;
temp.ceng++;
myqueue.push(temp);
}
}
if (cur.c>0&&cur.b<v2){ //v3->v2
temp=cur;
int tt=min(cur.a,v2-cur.b);
temp.c-=tt;
temp.b+=tt;
if (!used[temp.a][temp.b][temp.c]){
used[temp.a][temp.b][temp.c]=true;
temp.ceng++;
myqueue.push(temp);
}
}
if (cur.b>0&&cur.a<v1){ //v2->v1
temp=cur;
int tt=min(cur.a,v2-cur.b);
temp.b-=tt;
temp.a+=tt;
if (!used[temp.a][temp.b][temp.c]){
used[temp.a][temp.b][temp.c]=true;
temp.ceng++;
myqueue.push(temp);
}
}
}
return -1;
}
int main()
{
int casenumber;
scanf("%d",&casenumber);
while (casenumber--){
scanf("%d%d%d",&v1,&v2,&v3);
scanf("%d%d%d",&e.a,&e.b,&e.c);
b.a=v1;
if (v1<e.a+e.b+e.c){
printf("-1\n");
continue;
}
else printf("%d\n",BFS(b));
}
return 0;
}