1117-三个水杯

1117 - 三个水杯

时间限制:1秒 内存限制:128兆

题目描述

给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。

输入

第一行一个整数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

三个水杯问题其实就是对水杯里面的水进行互相倒的过程,我们可以用三维数组来标记每一次倒水后的状态,如果在倒水后发现之前出现过这个状态,那么就说明此时已经重复操作了,return出去就好

下面是dfs暴力代码

#include<stdio.h>
#include<string.h>
int zt[105][105][105];
int sa,sb,sc;
int flag,step;
int ea,eb,ec;
void dfs(int a,int b, int c,int num)
{
	if(flag==1&&num>step)//如果所需次数大于之前成功状态时的次数,返回上一步操作 
	return ;
	if(a==ea&&b==eb&&c==ec)//满足最终状态条件,进行判断 
	{
		if(step==0)//第一次的成功状态 
		step=num;
		else//不止一次能够达到成功状态 
		{
			if(step>num)
			step=num;
		}
		flag=1;
		return ;
	}
	for(int i=1;i<=6;i++)
	{
		if(i==1)//a向b倒水 
		{
			if(a>sb-b&&b!=sb)//a水杯向b水杯倒水,能将b水杯倒满的情况 
			{
				int x=b;
				a=a-sb+x;
				b=sb;
				if(zt[a][b][c]==1)
				{
					b=x;
					a=a-x+sb;
					continue ;
				}
				zt[a][b][c]=1;
				dfs(a,b,c,num+1);
				zt[a][b][c]=0;
				b=x;
				a=a-x+sb;
			}
			else//a向b倒水,把a水杯倒空的情况 
			{
				if(a!=0)
				{
					int x=a;
					b=b+x;
					a=0;
					if(b<=sb)
					{
						if(zt[a][b][c]==1)
						{
							a=x;
							b=b-x;
							continue ;
						}
						zt[a][b][c]=1;
						dfs(a,b,c,num+1);
						zt[a][b][c]=0;
					}
					a=x;
					b=b-x;
				}	
			}
		}
		if(i==2)//a向c倒水 
		{
			if(a>sc-c&&c!=sc) //将c倒满 
			{
				int x=c;
				a=a-sc+c;
				c=sc;
				if(zt[a][b][c]==1)
				{
					a=a-x+sc;
					c=x;
					continue ;
				}
				zt[a][b][c]=1;
				dfs(a,b,c,num+1);
				zt[a][b][c]=0;
				a=a-x+sc;
				c=x;
			}
			else//将a倒空 
			{
				if(a!=0)
				{
					int x=a;
					c=c+a;
					a=0;
					if(c<=sc)
					{
						if(zt[a][b][c]==1)
						{
							a=x;
							c=c-x;
							continue ;
						}
						zt[a][b][c]=1;
						dfs(a,b,c,num+1);
						zt[a][b][c]=0;
					}	
					a=x;
					c=c-x;
				}	
			}
		}
		if(i==3)//b向a倒水 
		{
			if(b<sa-a)//将b倒空 
			{
				if(b!=0)
				{
					int x=b;
					a=a+b;
					b=0;
					if(a<=sa)
					{
						if(zt[a][b][c]==1)
						{
							b=x;
							a=a-x;
							continue ;
						}
						zt[a][b][c]=1;
						dfs(a,b,c,num+1);
						zt[a][b][c]=0;
					}
					b=x;
					a=a-x;
				}
				
			}
			else//将a倒满 
			{
				int x=a;
				b=b-sa+a;
				a=sa;
				if(zt[a][b][c]==1)
				{
					a=x;
					b=b-x+sa;
					continue ;
				}
				zt[a][b][c]=1;
				dfs(a,b,c,num+1);
				zt[a][b][c]=0;
				a=x;
				b=b-x+sa;
			}
		}
		if(i==4)//b向c倒水 
		{
			if(b>sc-c&&c!=sc)//将c倒满 
			{
				int x=c;
				b=b-sc+c;
				c=sc;
				if(zt[a][b][c]==1)
				{
					b=b-x+sc;
					c=x;
					continue ;
				}
				zt[a][b][c]=1;
				dfs(a,b,c,num+1);
				zt[a][b][c]=0;
				b=b-x+sc;
				c=x;
			}
			else//将b倒空 
			{
				if(b!=0)
				{
					int x=b;
					c=c+b;
					b=0;
					if(c<=sc)
					{
						if(zt[a][b][c]==1)
						{
							b=x;
							c=c-x;
							continue ;
						}
						zt[a][b][c]=1;
						dfs(a,b,c,num+1);
						zt[a][b][c]=0;
					}
					b=x;
					c=c-x;
				}
				
			}
		}
		if(i==5)//c向a倒水 
		{
			if(c>sa-a&&a!=sa)//将a倒满 
			{
				int x=a;
				c=c-sa+a;
				a=sa;
				if(zt[a][b][c]==1)
				{
					c=c-x+sa;
					a=x;
					continue ;
				}
				zt[a][b][c]=1;
				dfs(a,b,c,num+1);
				zt[a][b][c]=0;
				c=c-x+sa;
				a=x;
			}
			else//将c倒空 
			{
				if(c!=0)
				{
					int x=c;
					a=a+c;
					c=0;
					if(zt[a][b][c]==1)
					{
						a=a-x;
						c=x;
						continue ;	
					}
					zt[a][b][c]=1;
					dfs(a,b,c,num+1);
					zt[a][b][c]=0;
					a=a-x;
					c=x;
				}
			}
		}
		if(i==6)//c向b倒水 
		{
			if(c>sb-b&&b!=sb)//将b倒满 
			{
				int x=b;
				c=c-sb+b;
				b=sb;
				if(zt[a][b][c]==1)
				{
					b=x;
					c=c-x+sb;
					continue ;
				}
				zt[a][b][c]=1;
				dfs(a,b,c,num+1);
				zt[a][b][c]=0;
				b=x;
				c=c-x+sb;
			}
			else//将c倒空 
			{
				int x=c;
				b=b+c;
				c=0;
				if(b<=sb)
				{
					if(zt[a][b][c]==1)
					{
						c=x;
						b=b-x;
						continue ;
					}
					zt[a][b][c]=1;
					dfs(a,b,c,num+1);
					zt[a][b][c]=0;
				}
				c=x;
				b=b-x;
			}
		}
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d %d %d",&sa,&sb,&sc);
		scanf("%d %d %d",&ea,&eb,&ec);
		if(sa==ea&&eb==0&&ec==0)
		printf("0\n");
		else
		{
			zt[sa][0][0]=1;
			dfs(sa,0,0,0);
			if(step!=0)
			printf("%d\n",step);
			if(step==0)
			printf("-1\n");
		}
		step=0;
		flag=0;
		memset(zt,0,sizeof(zt));	
	}
}

以下为向xzl借鉴的bfs代码,思路是一样的,代码中不再做说明

#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
int v1,v2,v3;
int e1,e2,e3;
struct Node
{
	int x,y,z,step;
	Node(){}
	Node(int xx,int yy,int zz,int ss) : x(xx) , y(yy) , z(zz) ,step(ss) {} 
};
int book[110][110][110];
int bfs(int x,int y,int z,int ss)
{
	memset(book,0,sizeof(book));
	queue<Node> Q;
	Q.push(Node(x,y,z,ss));
	book[x][y][z] = 1 ;
	while(!Q.empty())
	{
		Node u = Q.front();
		Q.pop();
		if(u.x==e1&&u.y==e2&&u.z==e3)
		{
			return u.step ; 
		}
		for(int i = 0 ; i < 6 ; i++)
		{
			Node s = u ;
			if(i == 0 ) // a - b
			{
				int  minn = min(s.x , v2 - s.y);
				s.x-=minn;
				s.y+=minn;
			}
			if(i == 1 ) // a - c
			{
				int  minn = min(s.x , v3 - s.z);
				s.x-=minn;
				s.z+=minn;
			} 
			if(i == 2 ) // b - a
			{
				int  minn = min(s.y , v1 - s.x);
				s.x+=minn;
				s.y-=minn;
			} 
			if(i == 3 ) // b - c
			{
				int  minn = min(s.y , v3 - s.z);
				s.z+=minn;
				s.y-=minn;
			} 
			if(i == 4 ) // c - b
			{
				int  minn = min(s.z , v2 - s.y);
				s.z-=minn;
				s.y+=minn;
			}
			if(i == 5 ) // c - a
			{
				int  minn = min(s.z , v1 - s.x);
				s.x+=minn;
				s.z-=minn;
			} 
			int sss = u.step + 1 ;
			if(book[s.x][s.y][s.z] == 0)
			{
				Q.push(Node(s.x,s.y,s.z,sss));
				book[s.x][s.y][s.z] = 1 ;
			}
		}
	}
	return -1;
}
int main()
{
	int n;
	scanf("%d",&n); 
	while(n--)
	{
		scanf("%d %d %d",&v1,&v2,&v3);
		scanf("%d %d %d",&e1,&e2,&e3);
		int ans = bfs(v1 , 0, 0 ,0);
		printf("%d\n",ans);
	}
} 

猜你喜欢

转载自blog.csdn.net/w__000000wbt/article/details/84854771