三个水杯
-
描述
-
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
-
输入
-
第一行一个整数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组测试数据
把原先判断6种状态的循环改成了两个:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 100
typedef struct
{
int gl[3];
int step;
}Glass;
queue<Glass> q;
int v[3];//用数组来存;
int e[3];
int f[MAX][MAX][MAX];
int flag;
void three_glasses();
int main()
{
int n,i;
Glass g;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
memset(f, 0, sizeof(f));
flag = 0;
while(!q.empty())
q.pop();
scanf("%d %d %d", &v[0],&v[1], &v[2]);
scanf("%d %d %d", &e[0], &e[1], &e[2]);
g.gl[0]= v[0];
g.gl[1] = 0;
g.gl[2] = 0;
g.step = 0;
f[g.gl[0]][g.gl[1]][g.gl[2]] = 1;
q.push(g);
three_glasses();
if(flag == 0)
printf("-1\n");
}
return 0;
}
void three_glasses()
{
int i, j, k,z;
while(!q.empty())
{
Glass g,t;
g = q.front();
q.pop();
for(i = 0; i < 3; i++)
for(j = i+1,k = 0;k < 2;j++, k++)
{
z = j % 3;//第i个给第z个倒水;
t = g;
if(t.gl[0] == e[0] && t.gl[1]== e[1] && t.gl[2] == e[2])
{
flag = 1;
printf("%d\n", t.step);
return ;
}
if(g.gl[i] && g.gl[z] != v[z])
{
if(g.gl[i] <= v[z] - g.gl[z])
{
t.gl[i] = 0;
t.gl[z] = g.gl[i] + g.gl[z];
}
else
{
t.gl[i] = g.gl[i] - (v[z] - g.gl[z]);
t.gl[z] = v[z];
}
t.step = g.step +1;
}
if(t.gl[0] >= 0 && t.gl[1] >= 0 && t.gl[2] >= 0 && t.gl[0] <= v[0] && t.gl[1] <= v[1] && t.gl[2] <= v[2] && f[t.gl[0]][t.gl[1]][t.gl[2]] == 0 )
{
f[t.gl[0]][t.gl[1]][t.gl[2]] = 1;
q.push(t);
}
}
}
}