uva10603倒水问题宽度优先遍历!

利用bfs解题,以三个杯子中现有水量作为一个“状态”,从一个状态不断扩展新的状态加入排队数组,这样既可保证找到目标水量时是经过了最少次数的倒水操作。

扩展新的状态节点是个稍微难一点的地方,先计算出i给j能倒得水量amount,等于i所剩水与j所差水的最小值。然后当amount!=0时进行倒水操作。vis是判重数组,只需要二维既可,因为三个杯子的水总量是不变的,两个杯子的水量相同时就表明是同一个状态。

难度不大,细心既可。

转载请注明出处,谢谢

http://blog.csdn.net/monkeyduck

#include<iostream>
#include<cstring>

using namespace std;

int vol[3],d,n,front,rear;
bool flag,vis[201][201];
struct Node
{
	int water[3],s;
};
Node result,state[40001];
void bfs()
{
	int i,j;
	front=rear=0;
	Node init,tnode;
	init.water[0]=0;init.water[1]=0;init.water[2]=vol[2];init.s=0;
	vis[0][0]=1;
	state[rear++]=init;
	while(front<rear)
	{
		tnode=state[front++];
		if (tnode.water[0]==d||tnode.water[1]==d||tnode.water[2]==d)
		{
			flag=1;
			result=tnode;
			break;
		}
		for (i=0;i<3;i++)
		{
			for (j=0;j<3;j++)
			{
				if (i!=j)
				{
					int amount=tnode.water[i]<vol[j]-tnode.water[j]?tnode.water[i]:vol[j]-tnode.water[j];
					if (amount!=0)
					{
						Node nNode;
						for (int k=0;k<3;k++)
							nNode.water[k]=tnode.water[k];
						nNode.water[i]=nNode.water[i]-amount;
						nNode.water[j]=nNode.water[j]+amount;
						nNode.s=tnode.s+amount;
						if (!vis[nNode.water[0]][nNode.water[1]])
						{
							vis[nNode.water[0]][nNode.water[1]]=1;
							state[rear++]=nNode;
						}
					}
				}
			}
		}
	}
}
int main()
{
	cin>>n;
	while(n--)
	{
		cin>>vol[0]>>vol[1]>>vol[2]>>d;
		flag=0;
		memset(vis,0,sizeof(vis));
		bfs();
		if (flag)
			cout<<result.s<<" "<<d<<endl;
		else
		{
			for (int i=d-1;i>=0;i--)
			{
				for (int j=0;j<=rear;j++)
				{
					Node nn=state[j];
					if (nn.water[0]==i||nn.water[1]==i||nn.water[2]==i)
					{
						cout<<nn.s<<" "<<i<<endl;
						flag=1;
						break;
					}
				}
				if (flag) break;
			}
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值