ACM pku 3414 Pots 关于bfs的一个好题

来源:互联网 发布:视频下载软件app 编辑:程序博客网 时间:2024/05/27 20:09
    题目给出了两个水桶A,B,以及一个数C,其中A和B分别代表它们的容量,对
它们可以有如下操作:
  1. FILL(i)        fill the pot i (1 ≤ i ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. POUR(i,j)    pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).
问桶里的水经过哪几个操作后能够达到C的容量。
这个题目可以用bfs把它做出来,对于两个桶的每一种状态,我们都可对它进行
六种操作,即FILL(1),FILL(2),DROP(1),DROP(2),POUR(1,2),POUR(2,1),
我们可以把它的每一种状态记录下来,一层一层的往下扩展,直到找到我们要
找的容量为止。不过这里有一个麻烦,就是要你输出得到容量C的过程。所以
对于每一个结点,我们都得对它设置一个pre指针,使它指向其父结点,等到
我们找到正确的结果之后,再沿着其父结点返回来找那条正确的路径。
具体代码如下:
  1. #include <iostream>
  2. #include <stack>
  3. #define Len 10000
  4. //#include <queue>
  5. using namespace std;
  6. struct Pot
  7. {
  8.      int x,y,step;
  9.      int flag;
  10. };
  11. struct Node
  12. {
  13.      Pot data;
  14.      struct Node *pre;
  15. };
  16. int A,B,C;
  17. Node *an[Len];
  18. Node nd[Len];
  19. int num;
  20. bool visit[110][110];
  21. int head,tail;
  22. stack<int> T;
  23. int bfs(int x,int y)
  24. {
  25.       Node *s,*t,*cur;
  26.       head = tail = 0;
  27.       num = 0;
  28.       cur = new Node;
  29.       cur->data.x = x;
  30.       cur->data.y = y;
  31.       cur->data.flag = 0;
  32.       cur->data.step = 0;
  33.       cur->pre = NULL;
  34.       an[head] = cur;
  35.       tail++;
  36.       visit[x][y] = true;
  37.       while(head != tail)
  38.       {
  39.             s = an[head++];
  40.             bool f;
  41.             for(int i=1;i<=6;++i)
  42.             {
  43.                   f = false;
  44.                   switch(i)
  45.                   {
  46.                         case 1:
  47.                               nd[num].data.x = A;
  48.                               nd[num].data.y = s->data.y;
  49.                               nd[num].data.flag = 1;
  50.                                break;
  51.                         case 2:
  52.                               nd[num].data.y = B;
  53.                               nd[num].data.x = s->data.x;
  54.                               nd[num].data.flag = 2;
  55.                                break;
  56.                         case 3:nd[num].data.x = 0;
  57.                                nd[num].data.y = s->data.y;
  58.                                nd[num].data.flag = 3;
  59.                                break;
  60.                         case 4:
  61.                                nd[num].data.x = s->data.x;
  62.                                nd[num].data.y = 0;
  63.                                nd[num].data.flag = 4;
  64.                                break;
  65.                         case 5:
  66.                                if(s->data.x + s->data.y > B)
  67.                                {
  68.                                       nd[num].data.x = s->data.x+s->data.y-B;
  69.                                       nd[num].data.y = B;
  70.                                       nd[num].data.flag = 5;
  71.                                }
  72.                                else{
  73.                                            nd[num].data.x = 0;
  74.                                            nd[num].data.y = s->data.x+s->data.y;
  75.                                            nd[num].data.flag = 5;
  76.                                }
  77.                                break;
  78.                         case 6:
  79.                                if(s->data.x+s->data.y > A)
  80.                                {
  81.                                        nd[num].data.x = A;
  82.                                        nd[num].data.y = s->data.x+s->data.y-A;
  83.                                        nd[num].data.flag = 6;
  84.                                }
  85.                                else{
  86.                                           nd[num].data.x = s->data.x+s->data.y;
  87.                                            nd[num].data.y = 0;
  88.                                            nd[num].data.flag = 6;
  89.                                }
  90.                                break;
  91.                   }
  92.                  nd[num].data.step = s->data.step+1;
  93.                   if(!visit[nd[num].data.x][nd[num].data.y])
  94.                   {
  95.                            visit[nd[num].data.x][nd[num].data.y] = true;
  96.                            nd[num].pre = s;
  97.                            if(nd[num].data.x == C || nd[num].data.y == C)
  98.                            {
  99.                                   Node *p = &nd[num];
  100.                                   while(p)
  101.                                   {
  102.                                         T.push(p->data.flag);
  103.                                         p = p->pre;
  104.                                   }
  105.                                   return nd[num].data.step;
  106.                            }
  107.                            else an[tail++] = &nd[num++];
  108.                   }
  109.             }
  110.       }
  111.       printf("impossible/n");
  112. }
  113. void input()
  114. {
  115.       cin>>A>>B>>C;
  116.       for(int i=0;i<=A;++i)
  117.       for(int j=0;j<=B;++j)
  118.       visit[i][j] = false;
  119.       if(C == 0) cout<<"0"<<endl;
  120.       else
  121.       cout<<bfs(0,0)<<endl;
  122.       int tag;
  123.       while(!T.empty())
  124.       {
  125.              tag = T.top();
  126.              T.pop();
  127.              switch(tag)
  128.              {
  129.                    case 0:break;
  130.                    case 1:cout<<"FILL(1)"<<endl;
  131.                           break;
  132.                    case 2:cout<<"FILL(2)"<<endl;
  133.                           break;
  134.                    case 3:cout<<"DROP(1)"<<endl;
  135.                           break;
  136.                    case 4:cout<<"DROP(2)"<<endl;
  137.                           break;
  138.                    case 5:cout<<"POUR(1,2)"<<endl;
  139.                           break;
  140.                    case 6:cout<<"POUR(2,1)"<<endl;
  141.                           break;
  142.              }
  143.       }
  144. }
  145. int main()
  146. {
  147.       input();
  148.       return 0;
  149. }

原创粉丝点击