hdu 1415 Jugs

来源:互联网 发布:创博网络 编辑:程序博客网 时间:2024/05/16 07:08

题目链接:

题目大意:这题是倒水问题,现在有两个容积为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");elseprintf("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');elseprintf("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是此次操作可以倒出的水量elseamount=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();}}