nyoj 21 三个水杯 隐式图转换举例

题目连接:http://59.69.128.200/JudgeOnline/problem.php?pid=21

题意:给三个容量不同的水杯,其中最大的那个水杯中装满水,然后三个杯子相互倒水,问从初始状态到目的状态至少要多少次。

解题思路:由于每次只能想其中一个杯子中倒水,并且,而且每次当前杯子中的水倒完,或者是将另一个杯子倒满为止。相当于从一个点到另一个点。

因此每次选择一个杯子向另外两个杯子倒水(除非倒水的杯子没有水)

 
#include<iostream>
#include<queue>
#include<memory.h>
#include<algorithm>
using namespace std;
int flat;
int v[103][103];
int x,y,z,p,q,r;
struct A
{int a,b,c;}m,k;
int main()
{
	/*freopen("1.txt","r",stdin);*/
	int n;cin>>n;
	while(n--)
	{
		cin>>x>>y>>z;cin>>p>>q>>r;
		queue<A> s,t;m.a=x;m.b=0;m.c=0;s.push(m);
		flat=0;int sum=0;
		memset(v,0,sizeof(v));
		while(1)
		{
			sum++;
			while(!s.empty())
			{
				k=s.front();
				m=s.front();int f1=x-m.a;int f2=y-m.b;int f3=z-m.c;
				v[k.b][k.c]=1;
				if(k.a==p&&k.b==q&&k.c==r){flat=1;break;}
				if(f1>0)
				{
					if(f1>=k.b&&!v[0][k.c]){m.a=k.a+k.b;m.b=0;m.c=k.c;t.push(m);}
					else if(f1<k.b&&!v[k.b-f1][k.c]){m.a=x;m.b=k.b-f1;m.c=k.c;t.push(m);}
					if(f1>=k.c&&!v[k.b][0]){m.a=k.a+k.c;m.b=k.b;m.c=0;t.push(m);}
					else if(f1<k.c&&!v[k.b][k.c-f1]){m.a=x;m.b=k.b;m.c=k.c-f1;t.push(m);}
				}
				if(f2>0)
				{
					if(f2>=k.a&&!v[k.b+k.a][k.c]){m.a=0;m.b=k.a+k.b;m.c=k.c;t.push(m);}
					else if(f2<k.a&&!v[y][k.c]){m.a=k.a-f2;m.b=y;m.c=k.c;t.push(m);}
					if(f2>=k.c&&!v[k.b+k.c][0]){m.a=k.a;m.b=k.b+k.c;m.c=0;t.push(m);}
					else if(f2<k.c&&!v[y][k.c-f2]){m.a=k.a;m.b=y;m.c=k.c-f2;t.push(m);};
				}
				if(f3>0)
				{
					if(f3>=k.a&&!v[k.b][k.c+k.a]){m.a=0;m.b=k.b;m.c=k.c+k.a;t.push(m);}
					else if(f3<k.a&&!v[k.b][z]){m.a=k.a-f3;m.b=k.b;m.c=z;t.push(m);}
					if(f3>=k.b&&!v[0][k.c+k.b]){m.a=k.a;m.b=0;m.c=k.c+k.b;t.push(m);}
					else if(f3<k.b&&!v[k.b-f3][z]){m.a=k.a;m.b=k.b-f3;m.c=z;t.push(m);};
				}
				s.pop();
			}
			if(flat)
				break;
			else
			{
				if(t.empty())
					break;
				while(!t.empty())
				{
					s.push(t.front());t.pop();
				}
			}
		}
		if(flat)
			cout<<sum-1<<endl;
		else
			cout<<"-1"<<endl;
	}
}        


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值