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 }

 

posted on 2015-12-04 23:19  蜘蛛侦探  阅读(159)  评论(0编辑  收藏  举报