http://acm.hdu.edu.cn/showproblem.php?pid=1495
搜索模拟出每此倒得情况就好,详情见代码\
(好困啊!!!!1)
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 using namespace std; 5 #define M 111 6 #define min(a,b) a<b?a:b 7 struct point{ 8 int v[5]; 9 int time; 10 }; 11 int res[5],vis[M][M]; 12 int bfs() 13 { 14 memset(vis,0,sizeof(vis)); 15 queue<point>Q; 16 point now,next; 17 now.v[2]=0;now.v[3]=0;now.v[1]=res[1];、、初始情况 18 now.time=0; 19 vis[now.v[1]][0]=1;、、记录瓶子和大杯子的情况,避免重复 20 Q.push(now); 21 while (!Q.empty()) 22 { 23 now=Q.front(); 24 Q.pop(); 25 if (now.v[1]==now.v[3]&&now.v[3]*2==res[1]) 26 return now.time; 27 for (int i=1;i<=3;i++) 28 { 29 for (int j=1;j<=3;j++) 30 { 31 if (i==j) continue; 32 int temp=min(now.v[i],res[j]-now.v[j]);、、选取能够倒的睡的体积 33 for (int k=1;k<=3;k++) 34 next.v[k]=now.v[k]; 35 next.v[i]-=temp; 36 next.v[j]+=temp; 37 if (vis[next.v[1]][next.v[3]]) continue; 38 vis[next.v[1]][next.v[3]]=1; 39 next.time=now.time+1; 40 Q.push(next); 41 } 42 } 43 } 44 return -1; 45 } 46 int main() 47 { 48 while (~scanf("%d %d %d",&res[1],&res[2],&res[3])) 49 { 50 if (!res[1]&&!res[2]&&!res[3]) break; 51 if (res[1]%2){ 、、如果总数不能被平分那么肯定是不行的 52 printf("NO\n"); 53 continue; 54 } 55 if (res[2]>res[3]) swap(res[2],res[3]);、、因为一般情况下这两个都是一大一小的,一个大于一半,一个小于一半,最后如果分出来了肯定是一半在瓶子里一半在打的那个杯子里,所以需要先找出哪个杯子是大的哪个是小的 56 int x=bfs(); 57 if (x==-1) printf("NO\n"); 58 else printf("%d\n",x); 59 } 60 return 0; 61 }