NYOJ 21-三个水杯(BFS搜索)


题目链接:
http://acm.nyist.net/JudgeOnline/problem.php?pid=21

三个水杯

时间限制: 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
//BFS
#include <stdio.h>
#include <queue>
#include <string.h>
#define maxn 100005
using namespace std;
int vis[105][105][105];
int e1, e2, e3;
int v1, v2, v3;

struct Node
{
	int v1, v2, v3, cnt;
};

int bfs()
{
	queue<Node>q;
	q.push((Node){v1, 0, 0, 0});
	memset(vis, 0, sizeof(vis));
	vis[v1][0][0] = 1;
	while(!q.empty())
	{
		Node p = q.front();
		int E1 = p.v1;
		int E2 = p.v2;
		int E3 = p.v3;
		int cnt = p.cnt;
		if(E1==e1 && E2==e2 && E3==e3)
			return cnt;
		//将1倒给2,判断可不可以倒满,下同
		if(E1 >= v2-E2 && !vis[E1-v2+E2][v2][E3])
		{
			vis[E1-v2+E2][v2][E3] = 1;
			q.push((Node){E1-v2+E2, v2, E3, cnt+1});
		}
		else
			if(E1 < v2-E2 && !vis[0][E2+E1][E3])
			{
				vis[0][E2+E1][E3] = 1;
				q.push((Node){0, E1+E2, E3, cnt+1});
			}
		//将1倒给3
		if(E1 >= v3-E3 && !vis[E1-v3+E3][E2][v3])
		{
			vis[E1-v3+E3][E2][v3] = 1;
			q.push((Node){E1-v3+E3, E2, v3, cnt+1});
		}
		else
			if(E1 < v3-E3 && !vis[0][E2][E3+E1])
			{
				vis[0][E2][E3+E1] = 1;
				q.push((Node){0, E2, E3+E1, cnt+1});
			}
		//将2倒给1
		if(E2 >= v1-E1 && !vis[v1][E2-v1+E1][E3])
		{
			vis[v1][E2-v1+E1][E3] = 1;
			q.push((Node){v1, E2-v1+E1, E3, cnt+1});
		}
		else
			if(E2 < v1-E1 && !vis[E1+E2][0][E3])
			{
				vis[E1+E2][0][E3] = 1;
				q.push((Node){E1+E2, 0, E3, cnt+1});
			}

		//将2倒给3
		if(E2 >= v3-E3 && !vis[E1][E2-v3+E3][v3])
		{
			vis[E1][E2-v3+E3][v3] = 1;
			q.push((Node){E1, E2-v3+E3, v3, cnt+1});
		}
		else
			if(E2 < v3-E3 && !vis[E1][0][E2+E3])
			{
				vis[E1][0][E2+E3] = 1;
				q.push((Node){E1, 0, E3+E2, cnt+1});
			}

		//将3倒给1
		if(E3 >= v1-E1 && !vis[v1][E2][E3-v1+E1])
		{
			vis[v1][E2][E3-v1+E1] = 1;
			q.push((Node){v1, E2, E3-v1+E1, cnt+1});
		}
		else
			if(E3 < v1-E1 && !vis[E1+E3][E2][0])
			{
				vis[E1+E3][E2][0] = 1;
				q.push((Node){E1+E3, E2, 0, cnt+1});
			}
		//将3倒给2
		if(E3 >= v2-E2 && !vis[E1][v2][E3-v2+E2])
		{
			vis[E1][v2][E3-v2+E2] = 1;
			q.push((Node){E1, v2, E3-v2+E2, cnt+1});
		}
		else
			if(E3 < v2-E2 && !vis[E1][E2+E3][0])
			{
				vis[E1][E2+E3][0] = 1;
				q.push((Node){E1, E3+E2, 0, cnt+1});
			}
		q.pop();
	}
	return -1;
}
int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d%d%d", &v1, &v2, &v3);
		scanf("%d%d%d", &e1, &e2, &e3);
		int ans = bfs();
		printf("%d\n", ans);
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_31281327/article/details/76335741