题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1495
中文题目就不用我解释题意了,直接上代码,代码里面写的很清楚。
关键解决问题是怎样倒,有三个瓶子,所以有6种倒发,每次倒的时候要判断是否能倒满。
简单BFS、
代码如下:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <set> #include <map> #include <queue> using namespace std; /* freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); */ int s,n,m; bool visit[105][105];//因为n+m=s,所以只用n,m标记即可 int a[3];//表示三个瓶子的最大体积,s、n、m依次为0、1、2 struct xh { int v[3]; int step;//倒的次数 }w,ww; void bfs() { a[0]=s;a[1]=n;a[2]=m; queue<xh>q; memset(visit,false,sizeof(visit)); w.v[0]=s; w.v[1]=w.v[2]=0; w.step=0; visit[0][0]=true; q.push(w); while(!q.empty()) { ww=q.front(); q.pop(); if((ww.v[1]==s/2&&ww.v[2]==s/2)||(ww.v[0]==s/2&&ww.v[2]==s/2)||(ww.v[0]==s/2&&ww.v[1]==s/2)) { printf("%d\n",ww.step); return ; } for(int i=0;i<3;i++) { if(ww.v[i]>0)//将i中的水倒向j中,i空瓶,跳过 for(int j=0;j<3;j++) { w=ww; if(i==j) continue; if(w.v[i]+w.v[j]>a[j])//i+j>j瓶的最大体积 { w.v[i]=w.v[i]-(a[j]-w.v[j]); w.v[j]=a[j];//注意这两个的顺序不能反 } else//i+j<=j瓶的最大体积 { w.v[j]+=w.v[i]; w.v[i]=0;//注意这两个的顺序也不能反 } if(!visit[w.v[1]][w.v[2]]) { visit[w.v[1]][w.v[2]]=true; w.step++; q.push(w); } } } } printf("NO\n"); } int main() { while(cin>>s>>n>>m&&s+n+m) { if(s%2) { printf("NO\n"); continue; } if(n==m) { printf("1\n"); continue; } bfs(); } return 520; }