poj 1606 Jugs

本文详细介绍了如何通过C++编程语言解决经典的水壶装水问题,涉及状态转移矩阵、广度优先搜索算法以及利用队列进行路径记录。文章通过实例演示了如何将问题抽象为图论中的最短路径问题,并提供了完整的代码实现。

     与3414类似,基本改几句话就可以直接交了。

 

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define N 101
    using namespace std;
    int a,b,c;
    bool vis[N][N];

    char str[7][11] = {"lala","fill A","fill B ","pour A B","pour B A","empty A","empty B"};

    typedef struct _Node{
    int cou,a,b;
    struct _Node *pre;
    int way;
    }Node;
    Node queue[N*N];

    void display(Node n)
    {
        if(n.pre==NULL)
        {
           printf("%s\n",str[n.way]);
        }
        else
        {
            display(*n.pre);
            printf("%s\n",str[n.way]);
        }
    }


    int main(void)
    {
        while(scanf("%d %d %d",&a,&b,&c)!=EOF)
        {
          int head,tail;
          memset(vis,false,sizeof(vis));
          vis[0][0] =  true;
          Node now,next;
          now.a = a; now.b = 0; now.cou = 1; now.pre = NULL; now.way = 1;//分别装满2个瓶的情况
          next.a = 0; next.b = b; next.cou = 1; next.pre = NULL; next.way = 2;
          head = 1; tail = 3;
          vis[a][0] = true; vis[0][b] = true; vis[0][0] = true;
          queue[1] = now; queue[2] = next;
          bool flag = false;
          Node ans;
          while(!flag)
          {
              int count = tail - head;
              if(count<=0)
                break;
              while(count--)
              {
                  if(queue[head].b==c)
                  {
                      flag = true;
                      ans = queue[head];
                      break;
                  }
                  Node tmp;
                  tmp.way = 1; tmp.a = a; tmp.b = queue[head].b; tmp.cou = queue[head].cou+1;
                  tmp.pre = &queue[head];
                  if(!vis[tmp.a][tmp.b])
                  {
                   vis[tmp.a][tmp.b] = true;
                   queue[tail++] = tmp;
                  }
                  tmp.way = 2; tmp.a = queue[head].a; tmp.b = b;
                  if(!vis[tmp.a][tmp.b])
                  {
                   vis[tmp.a][tmp.b] = true;
                   queue[tail++] = tmp;
                  }
                  tmp.way = 3;
                  if(queue[head].a+queue[head].b>b)
                  {
                   tmp.a = (queue[head].a+queue[head].b) - b;
                  }
                  else
                  {
                     tmp.a = 0; tmp.b = queue[head].b+queue[head].a;
                  }
                  if(!vis[tmp.a][tmp.b])
                  {
                   vis[tmp.a][tmp.b] = true;
                   queue[tail++] = tmp;
                  }
                  tmp.way = 4;
                  if(queue[head].a+queue[head].b>a)
                  {
                   tmp.b = (queue[head].a+queue[head].b) - a; tmp.a = a;
                  }
                  else
                  {
                     tmp.b = 0; tmp.a = queue[head].b+queue[head].a;
                  }
                  if(!vis[tmp.a][tmp.b])
                  {
                   vis[tmp.a][tmp.b] = true;
                   queue[tail++] = tmp;
                  }
                  tmp.way = 5;
                  tmp.a = 0; tmp.b = queue[head].b;
                  if(!vis[tmp.a][tmp.b])
                  {
                   vis[tmp.a][tmp.b] = true;
                   queue[tail++] = tmp;
                  }
                  tmp.way = 6;
                  tmp.a = queue[head].a; tmp.b = 0;
                  if(!vis[tmp.a][tmp.b])
                  {
                   vis[tmp.a][tmp.b] = true;
                   queue[tail++] = tmp;
                  }
              }
              ++head;
          }
          if(flag)
          {
          display(ans);
          cout<<"success"<<endl;
          }

        }


        return 0;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值