思路:abc三个水杯 一共有六种倒水方式。a-b,a-c ; b-a,b-c;c-d;广搜着6种方式即可。但是得判断杯子里的水放进另外一个杯子放不放的下,另外一个杯子需要多少水,杯子子里有没有水可放。不要忘记目标和初始状态一样那种情况。
三个水杯
时间限制:
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<stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define QUEUELEN 1000000
int d,b,c, flag;//abc表示三个杯子的容积
int vis[101][101][101];
typedef struct
{
int x;
int y;
int z;
int pre;//倒水的次数
}DATA;//xyz表示三个杯子现在有多少水。
DATA data[QUEUELEN];
typedef struct
{
int head;
int tail;
}SQType;
//队列的初始化
SQType *SQTypeInit()
{
SQType *q;
if(q=(SQType *)malloc(sizeof(SQType)))
{
q->head=0;
q->tail=0;
return q;
}
else
{
return NULL;
}
}
//判断空队列
int SQTypeIsEmpty(SQType *q)
{
int temp;
temp=q->head==q->tail;
return temp;
}//入队
int InSQType(SQType *q,DATA a)
{
if (q->tail==QUEUELEN)
{
printf("队列满鸟。。。");
return 0;
}
else
{
data[q->tail++]=a;
return 1;
}
}
//出队列
int OutSQType(SQType *q,DATA &a)
{
if(q->head==q->tail)
{
printf("亲,队列是空的。。。");
return 0;
}
else
{ a=data[q->head++];
return 1;
}
}
bool bfs(int x,int y,int z,int zx,int zy,int zz)
{ if(x==zx&&y==zy&&z==zz)//目标是出事状态。 {
printf("%d\n",0);flag=1;return 1;}
SQType *shuibei=SQTypeInit();
DATA a={x,y,z,0};
InSQType(shuibei,a);
vis[x][y][z]=1;
while(!SQTypeIsEmpty(shuibei))
{ OutSQType(shuibei,a);
if(a.x!=0&&a.y<b)
{ int nx=a.x-(b-a.y)>0?a.x-(b-a.y):0;//判断a杯子倒水能不能全部倒进b杯子。能则nx=0;否则等于a水-b杯子需要的水
int ny=a.x-(b-a.y)>0?a.y+b-a.y:a.y+a.x;判断a杯子的水是否能装满自己 能则等于b不能则等于 a水加b水
int nz=a.z;
if(nx==zx&&ny==zy&&nz==zz)
{
printf("%d\n",a.pre+1);flag=1;return 1;
}
if(vis[nx][ny][nz]==0)
{
DATA n;
n.x=nx;
n.y=ny;
n.z=nz;
n.pre=a.pre+1;
InSQType(shuibei,n);
vis[nx][ny][nz]=1;
}
}
if(a.x!=0&&a.z<c)
{ int nx=a.x-(c-a.z)>0?a.x-(c-a.z):0;//同上面的原理一样
int ny=a.y;
int nz=a.x-(c-a.z)>0?a.z+(c-a.z):a.z+a.x;
if(nx==zx&&ny==zy&&nz==zz)
{
printf("%d\n",a.pre+1);flag=1;return 1;
}
if(vis[nx][ny][nz]==0)
{
DATA n;
n.x=nx;
n.y=ny;
n.z=nz;
n.pre=a.pre+1;
InSQType(shuibei,n);
vis[nx][ny][nz]=1;
}
}
if(a.y!=0)//b杯子有水
{
int nx=a.x+a.y;b杯子倒入a杯子不需要考虑 直接可以倒进去
int ny=0;
int nz=a.z;
if(nx==zx&&ny==zy&&nz==zz)
{
printf("%d\n",a.pre+1);flag=1;return 1;
}
if(vis[nx][ny][nz]==0)
{
DATA n;
n.x=nx;
n.y=ny;
n.z=nz;
n.pre=a.pre+1;
InSQType(shuibei,n);
vis[nx][ny][nz]=1;
}
}
if(a.y!=0&&a.z<c)
{
int nx=a.x;
int ny=a.y-(c-a.z)>0?a.y-(c-a.z):0;
int nz=a.y-(c-a.z)>0?a.z+(c-a.z):a.z+a.y;
if(nx==zx&&ny==zy&&nz==zz)
{
printf("%d\n",a.pre+1);flag=1;return 1;
}
if(vis[nx][ny][nz]==0 )
{
DATA n;
n.x=nx;
n.y=ny;
n.z=nz;
n.pre=a.pre+1;
InSQType(shuibei,n);
vis[nx][ny][nz]=1;
}
}
if(a.z!=0)
{
int nx=a.x+a.z;
int nz=0;
int ny=a.y;
if(nx==zx&&ny==zy&&nz==zz)
{
printf("%d\n",a.pre+1);flag=1;return 1;
}
if(vis[nx][ny][nz]==0)
{
DATA n;
n.x=nx;
n.y=ny;
n.z=nz;
n.pre=a.pre+1;
InSQType(shuibei,n);
vis[nx][ny][nz]=1;
}
}
if(a.z!=0&&a.y<b)
{
int nx=a.x;
int ny=b-a.y>a.z?a.y+a.z:b;判断b杯子能否装下c杯子里的水能装下则等于a.y+a.z c杯子此时没水。装不下则可以装满就直接等于b c此时等于c杯子的水减去b杯子需要多少水。
int nz=b-a.y>a.z?0:a.z-(b-a.y);
if(nx==zx&&ny==zy&&nz==zz)
{
printf("%d\n",a.pre+1);flag=1;
return 1;
}
if(vis[nx][ny][nz]==0)
{
DATA n;
n.x=nx;
n.y=ny;
n.z=nz;
n.pre=a.pre+1;
InSQType(shuibei,n);
vis[nx][ny][nz]=1;
}
}
}
}
int main()
{
int n,za,zb,zc;
scanf("%d",&n);
while(n--)
{ flag=0;
scanf("%d%d%d",&d,&b,&c);
scanf("%d%d%d",&za,&zb,&zc);
memset(vis,0,sizeof(vis));
bfs(d,0,0,za,zb,zc);
if(flag==0)printf("%d\n",-1);
}
}