三个水杯

三个水杯

时间限制: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 <queue>
#define Max_w 205

using namespace std;

int v1_e, v1_h;
int v2_e, v2_h;
int v3_e, v3_h;
int visited[Max_w][Max_w][Max_w] = {0};
typedef struct cup{
	int v1;
	int v2;
	int v3;
	int step;
}Cup;

void bfs(Cup c);
int main (){
	
	int N;
	int i, j, d;
	Cup c;

	scanf("%d", &N);
	while(N--){
		memset(visited, 0, sizeof(visited));
		scanf("%d %d %d", &v1_h, &v2_h, &v3_h);
		scanf("%d %d %d", &v1_e, &v2_e, &v3_e);
		if(v1_h == v1_e && 0 == v2_e && 0 == v3_e){
             printf("0\n");
             continue;
        }
		visited[v1_h][0][0] = 1;
		c.v1 = v1_h; c.v2 = 0; c.v3 = 0;
		c.step = 0;
		bfs(c);
	}

	return 0;
}	


void bfs(Cup c){
	
	int i;
	queue<Cup> Q;
	Cup temp, temp1;
	
	Q.push(c);
	while (!Q.empty()){
		temp1 = Q.front();
		Q.pop();
		if(temp1.v1 == v1_e && temp1.v2 == v2_e && temp1.v3 == v3_e){
			printf("%d\n", temp1.step);
			return ;
		}
		for(i = 0; i < 6; i++){
			temp = temp1;
			if(i == 0 && temp.v1 != 0 && temp.v2 != v2_h){
				if(temp.v1 >= v2_h - temp.v2){
					temp.v1 -= (v2_h - temp.v2);
					temp.v2 = v2_h;
				}
				else{
					temp.v2 += temp.v1;
					temp.v1 = 0;
				}
				temp.step ++;
				if(!visited[temp.v1][temp.v2][temp.v3]){
					visited[temp.v1][temp.v2][temp.v3] = 1;
					Q.push(temp);
				}
			}
			if(i == 1 && temp.v1 != 0 && temp.v3 != v3_h){
				if(temp.v1 >= v3_h - temp.v3){
					temp.v1 -= (v3_h - temp.v3);
					temp.v3 = v3_h;
				}
				else{
					temp.v3 += temp.v1;
					temp.v1 = 0;
				}
				temp.step ++;
				if(!visited[temp.v1][temp.v2][temp.v3]){
					visited[temp.v1][temp.v2][temp.v3] = 1;
					Q.push(temp);
				}
			}
			if(i ==  2 && temp.v2 != 0 && temp.v3 != v3_h){
				if(temp.v2 >= v3_h - temp.v3){
					temp.v2 -= (v3_h - temp.v3);
					temp.v3 = v3_h;
				}
				else{
					temp.v3 += temp.v2;
					temp.v2 = 0;
				}
				temp.step ++;
				if(!visited[temp.v1][temp.v2][temp.v3]){
					visited[temp.v1][temp.v2][temp.v3] = 1;
					Q.push(temp);
				}
			}
			if(i == 3 && temp.v2 != 0 && temp.v1 != v1_h){
				if(temp.v2 >= v1_h - temp.v1){
					temp.v2 -= (v1_h - temp.v1);
					temp.v1 = v1_h;
				}
				else{
					temp.v1 += temp.v2;
					temp.v2 = 0;
				}
				temp.step ++;
				if(!visited[temp.v1][temp.v2][temp.v3]){
					visited[temp.v1][temp.v2][temp.v3] = 1;
					Q.push(temp);
				}
			}
			if(i == 4 && temp.v3 != 0 && temp.v2 != v2_h){
				if(temp.v3 >= v2_h - temp.v2){
					temp.v3 -= (v2_h - temp.v2);
					temp.v2 = v2_h;
				}
				else{
					temp.v2 += temp.v3;
					temp.v3 = 0;
				}
				temp.step ++;
				if(!visited[temp.v1][temp.v2][temp.v3]){
					visited[temp.v1][temp.v2][temp.v3] = 1;
					Q.push(temp);
				}
			}
			if(i == 5 && temp.v3 != 0 && temp.v1 != v1_h){
				if(temp.v3 >= v1_h - temp.v1){
					temp.v3 -= (v1_h - temp.v1);
					temp.v1 = v1_h;
				}
				else{
					temp.v1 += temp.v3;
					temp.v3 = 0;
				}
				temp.step ++;
				if(!visited[temp.v1][temp.v2][temp.v3]){
					visited[temp.v1][temp.v2][temp.v3] = 1;
					Q.push(temp);
				}
			}
		}
	}
	printf("%d\n", -1);
}        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值