三个水杯
时间限制: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
这是我写过最长的模拟题,没有之一
代码
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
//三个水杯广搜一遍
const int maxn=101;
bool visited[maxn][maxn][maxn];//出现过的状态标记为1
int V1,V2,V3;//三个水杯的体积
int E1,E2,E3;//目标状态
struct node
{
int A1,A2,A3;
int steap;
};
void BFS(int steap,int A1,int A2,int A3)//传入倒水次数,当前状态
{
queue<node>q;
node star;
star.A1=A1;
star.A2=A2;
star.A3=A3;
star.steap=steap;
q.push(star);
memset(visited,false,sizeof(visited));
visited[star.A1][star.A2][star.A3]=1;//初始状态标记为已出现
while(!q.empty())
{
star=q.front();
q.pop();
//接着就是6种搜索方向
//当搜索到的状态满足目标状态就输出,出现重复状态不允许入队
node end;
if(star.A1>0)//A1有水
{
if(star.A2<V2)//A2没满就可以从A1倒给A2
{
if(star.A1<=V2-star.A2)//可以把A1全部倒进A2
{
end.A1=0;
end.A2=star.A2+star.A1;
end.A3=star.A3;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
else//A1倒一部分进A2,把A2充满
{
end.A1=star.A1-(V2-star.A2);
end.A2=V2;
end.A3=star.A3;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
}
if(star.A3<V2)//A3没满就可以从A1倒给A3
{
if(V3-star.A3>=star.A1)//如果A1可以全部倒给A3
{
end.A1=0;
end.A2=star.A2;
end.A3=star.A1+star.A3;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
else//A1倒一部分给A3把A3充满
{
end.A1=star.A1-(V3-star.A3);
end.A2=star.A2;
end.A3=V3;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
}
}
if(star.A2>0)//如果A2有水
{
if(star.A1<V1)//A1没满,可以从A2倒向A1
{
if(V1-star.A1>=star.A2)//把A2全部倒进A1
{
end.A1=star.A1+star.A2;
end.A2=0;
end.A3=star.A3;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
else//A2一部分倒进A1使A1充满
{
end.A1=V1;
end.A2=star.A2-(V1-star.A1);
end.A3=star.A3;
end.steap=star.steap;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
}
if(star.A3<V3)//如果A3没满,可以从A2倒向A3
{
if(V3-star.A3>=star.A2)//把A2全部倒进A3
{
end.A1=star.A1;
end.A2=0;
end.A3=star.A3+star.A2;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
else//把A2部分倒进A3使A3充满
{
end.A1=star.A1;
end.A2=star.A2-(V3-star.A3);
end.A3=V3;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
}
}
if(star.A3>0)//如果A3有水
{
if(star.A1<V1)//A1没满,可以从A3倒向A1
{
if(V1-star.A1>=star.A3)//把A3全部倒进A1
{
end.A1=star.A1+star.A3;
end.A2=star.A2;
end.A3=0;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
else//A3部分倒进A1使A1充满
{
end.A1=V1;
end.A2=star.A2;
end.A3=star.A3-(V1-star.A1);
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
}
if(star.A2<V2)//如果A2没满,可以从A3倒向A2
{
if(V2-star.A2>=star.A3)//把A3全部倒进A2
{
end.A1=star.A1;
end.A2=star.A2+star.A3;
end.A3=0;
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
else//A3部分倒进A2使A2充满
{
end.A1=star.A1;
end.A2=V2;
end.A3=star.A3-(V2-star.A2);
end.steap=star.steap+1;
if(end.A1==E1&&end.A2==E2&&end.A3==E3)
{
printf("%d\n",end.steap);
return;
}
if(visited[end.A1][end.A2][end.A3]==0)
{
q.push(end);
visited[end.A1][end.A2][end.A3]=1;
}
}
}
}
}
printf("-1\n");
return;
}
int main()
{
int N;
scanf("%d",&N);
while(N--)
{
scanf("%d%d%d%d%d%d",&V1,&V2,&V3,&E1,&E2,&E3);
if(E1+E2+E3>V1)//两种特判
{
printf("-1\n");
continue;
}
if(E1==V1&&E2==0&&E3==0)
{
printf("0\n");
continue;
}
BFS(0,V1,0,0);
}
}