hdu 1415 Jugs

题目链接:

题目大意:这题是倒水问题,现在有两个容积为a和b的水壶,对每个水壶可以进行4种操作,两个水壶之间相互倒水(一个水壶倒空或者一个水壶倒满为止),从水农头那里灌水(将水壶灌满为止),向外倒水(将水壶倒空为止),问对这两个水壶进行这样的一系列操作是否可以量出容积为c的水(两个杯子中有一个水壶中的水的容积恰好为c)
     这里添加一个水壶编号为0,容积为a和b的水壶分别编号为1和2,编号为0的水壶的容积置为a+b(保证0号水壶可以向1或2中加水,或者1或2向0中加水),再用BFS来进行求解.

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=110;
int sh[maxn],result;
int vis[maxn][maxn];
struct node
{
	int v[3];
	int fa;
}q[maxn*maxn];
node path[maxn*maxn];
void Print_path(int ans)
{
	int i=0,j,k;
	node p1,p2;
	while(q[ans].fa!=ans)
	{
		path[i++]=q[ans];
		ans=q[ans].fa;
	}
	path[i]=q[ans];
	while(i>=1)
	{
		p1=path[i];
		p2=path[--i];
		if(p1.v[0]==p2.v[0])//用标号为0的水壶中德前后两个状态作为判断标准
		{
			if(p1.v[1]<p2.v[1])
				printf("pour B A\n");
			else
				printf("pour A B\n");
		}
		else
		{
			for(j=1;j<3;j++)
				if(p1.v[j]==p2.v[j])
					break;
			k=3-j;
			if(p1.v[k]<p2.v[k])
				printf("fill %c\n",k-1+'A');
			else
				printf("empty %c\n",k-1+'A');
		}
	}
	printf("success\n\n");
}
void bfs()
{
	int i,j,k,start=0,tail=1;
	int amount;
	q[0].v[0]=sh[0];
	q[0].v[1]=q[0].v[2]=q[0].fa=0;
	vis[0][0]=1;
	while(start<tail)
	{
		node &u=q[start];
		if(u.v[1]==result||u.v[2]==result)
		{
			Print_path(start);//到达目标,打印方案
			return;
		}
		for(i=0;i<3;i++)//标号为i的水壶向标号为j的水壶中倒水
			for(j=0;j<3;j++)
				if(i!=j)
				{
					node &v=q[tail];
					if(u.v[i]<sh[j]-u.v[j])
						amount=u.v[i];//amount是此次操作可以倒出的水量
					else
						amount=sh[j]-u.v[j];
					for(k=0;k<3;k++)
						v.v[k]=u.v[k];//扩展新节点
					v.v[i]-=amount;//倒出
					v.v[j]+=amount;//倒进
					if(!vis[v.v[1]][v.v[2]])
					{
						vis[v.v[1]][v.v[2]]=1;//标记为已访问
						v.fa=start;
						tail++;
					}
				}
				start++;
	}
}
int main(void)
{
	while(scanf("%d%d%d",&sh[1],&sh[2],&result)!=EOF)
	{
		sh[0]=sh[1]+sh[2];
		memset(vis,0,sizeof(vis));
		bfs();
	}
}



 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值