三个水杯
Time Limit: 1000ms
Memory Limit: 128000KB
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。
Input
第一行一个整数N(0<N<50)表示N组测试数据
接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态
接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态
Output
每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1
Sample Input
2 6 3 1 4 1 1 9 3 2 7 1 1
Sample Output
3 -1
方法一:
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int v1,v2,v3,e1,e2,e3;
int vis[110][110][110];
struct node{
int a,b,c;
int step;
};
int bfs(){
node n;
queue<node> q;
q.push(node{v1,0,0,0});
int flag=0,k;
while(!q.empty()){
n=q.front();
q.pop();
if(n.a==e1 && n.b==e2 && n.c==e3){
flag=1;
break;
}
if(vis[n.a][n.b][n.c]) continue;
vis[n.a][n.b][n.c]=1;
k=(n.a >= v2-n.b) ? (v2-n.b):n.a;
q.push(node{n.a-k,n.b+k,n.c,n.step+1});
k=(n.a >= v3-n.c) ? (v3-n.c):n.a;
q.push(node{n.a-k,n.b,n.c+k,n.step+1});
k=(n.b >= v1-n.a) ? (v1-n.a):n.b;
q.push(node{n.a+k,n.b-k,n.c,n.step+1});
k=(n.b >= v3-n.c) ? (v3-n.c):n.b;
q.push(node{n.a,n.b-k,n.c+k,n.step+1});
k=(n.c >= v1-n.a) ? (v1-n.a):n.c;
q.push(node{n.a+k,n.b,n.c-k,n.step+1});
k=(n.c >= v2-n.b) ? (v2-n.b):n.c;
q.push(node{n.a,n.b+k,n.c-k,n.step+1});
}
if(flag) printf("%d\n",n.step);
else printf("-1\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
memset(vis,0,sizeof(vis));
scanf("%d%d%d%d%d%d",&v1,&v2,&v3,&e1,&e2,&e3);
bfs();
}
return 0;
}
方法二:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int v[4],e[4];
int vis[110][110][110];
struct node{
int v[4]; //倒水过程中杯子中盛水情况
int s;
}temp;
void pour(int a,int b){ //从a中倒水倒入b杯子中
int sum=temp.v[a]+temp.v[b];
if(sum>=v[b]) temp.v[b]=v[b];
else temp.v[b]=sum;
temp.v[a]=sum-temp.v[b];
}
void bfs(){
queue<node> q;
node cnt;
memset(vis,0,sizeof(vis));
temp.v[1]=v[1];temp.v[2]=0;temp.v[3]=0;temp.s=0;
q.push(temp);
vis[temp.v[1]][temp.v[2]][temp.v[3]]=1;
while(!q.empty()){
cnt=q.front();q.pop();
if(cnt.v[1]==e[1]&&cnt.v[2]==e[2]&&cnt.v[3]==e[3]){
printf("%d\n",cnt.s);
return;
}
for(int i=1;i<4;i++){
for(int j=1;j<4;j++){
if(i!=j){
temp=cnt; //重复几次倒水情况,要置于初始值
pour(i,j); //倒水
if(!vis[temp.v[1]][temp.v[2]][temp.v[3]]){
temp.s++;
q.push(temp);
vis[temp.v[1]][temp.v[2]][temp.v[3]]=1;
}
}
}
}
}
printf("-1\n");
}
int main(){
int n;
cin >> n;
while(n--){
scanf("%d%d%d",&v[1],&v[2],&v[3]);
scanf("%d%d%d",&e[1],&e[2],&e[3]);
bfs();
}
return 0;
}