zoukankan      html  css  js  c++  java
  • Pots POJ

    典型的倒水问题:

    即把两个水杯的每种状态视为bfs图中的点,如果两种状态可以转化,即可认为二者之间可以连一条边。

    有3种倒水的方法,对应2个杯子,共有6种可能的状态转移方式。即相当于图中想走的方法有6种,依次枚举即可。

    用一个二维数组标记状态,以免重复。

    难点在于输出路径,即bfs回溯。

    我的处理方法是,在bfs的队列基础上,用一个vector保存每一个可能的状态,即每个状态对应一个编号。同时结构体中不仅保存每个状态的信息,而且还要保存每个状态的对应编号和上一个状态的对应编号。

    那么,当bfs到达终点后,就可以从后向前进行回溯,找到路径,然后反向输出即可。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #include <vector>
      5 using namespace std;
      6 int Va,Vb,C;
      7 struct pot
      8 {
      9     int a,b,step,t,my,last;
     10 };
     11 bool vis[105][105];
     12 int a[10000];
     13 queue<pot>que;
     14 vector<pot>pre;
     15 int bfs()
     16 {
     17     while(!que.empty())
     18         que.pop();
     19     pot s=pot{0,0,-1,0,0,-1};
     20     que.push(s);
     21     vis[0][0]=1;
     22     pre.push_back(s);
     23     while(!que.empty())
     24     {
     25         pot now=que.front();
     26         que.pop();
     27         for(int i=0;i<6;i++)
     28         {
     29             pot tmp=now;
     30             if(i==0)//fill(1)
     31                 tmp.a=Va;
     32             else if(i==1)//fill(2)
     33                 tmp.b=Vb;
     34             else if(i==2)//drop(1)
     35                 tmp.a=0;
     36             else if(i==3)//drop(2)
     37                 tmp.b=0;
     38             else if(i==4)//pour(1,2)
     39             {
     40                 if(tmp.a>Vb-tmp.b)
     41                 {
     42                     tmp.a-=(Vb-tmp.b);
     43                     tmp.b=Vb;
     44                 }
     45                 else
     46                 {
     47                     tmp.b+=tmp.a;
     48                     tmp.a=0;
     49                 }
     50             }
     51             else if(i==5)//pour(2,1)
     52             {
     53                 if(tmp.b>Va-tmp.a)
     54                 {
     55                     tmp.b-=(Va-tmp.a);
     56                     tmp.a=Va;
     57                 }
     58                 else
     59                 {
     60                     tmp.a+=tmp.b;
     61                     tmp.b=0;
     62                 }
     63             }
     64             if(!vis[tmp.a][tmp.b])
     65             {
     66                 tmp.step=i;
     67                 tmp.t=now.t+1;
     68                 tmp.last=now.my;
     69                 pre.push_back(tmp);
     70                 tmp.my=pre.size()-1;
     71                 vis[tmp.a][tmp.b]=1;
     72                 que.push(tmp);
     73                 if(tmp.a==C||tmp.b==C)
     74                     return tmp.t;
     75             }
     76         }
     77     }
     78     return -1;
     79 }
     80 void print(int u)
     81 {
     82     if(u==0)
     83         printf("FILL(1)
    ");
     84     else if(u==1)
     85         printf("FILL(2)
    ");
     86     else if(u==2)
     87         printf("DROP(1)
    ");
     88     else if(u==3)
     89         printf("DROP(2)
    ");
     90     else if(u==4)
     91         printf("POUR(1,2)
    ");
     92     else if(u==5)
     93         printf("POUR(2,1)
    ");
     94 }
     95 int main()
     96 {
     97     while(scanf("%d%d%d",&Va,&Vb,&C)!=EOF)
     98     {
     99         memset(vis,0,sizeof(vis));
    100         pre.clear();
    101         int ans=bfs();
    102         if(ans==-1)
    103             printf("impossible
    ");
    104         else
    105         {
    106             printf("%d
    ",ans);
    107             memset(a,0,sizeof(a));
    108             int p=pre.size()-1;
    109             int cnt=0;
    110             while(pre[p].last!=-1)
    111             {
    112                 a[++cnt]=pre[p].step;
    113                 p=pre[p].last;
    114             }
    115             for(int i=cnt;i>=1;i--)
    116                 print(a[i]);
    117         }
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    linux中公钥和私钥的区别以及关系
    PAM
    57 容器(十一)——Collections容器工具类
    56 容器(十)——Iterator迭代器遍历容器
    55 重载需要注意的地方
    54 容器(九)——HashSet
    53 容器(八)——TreeMap 红黑树
    52 权限修饰符
    51 方法重写需要注意的地方
    50 多态,为什么总是要用父类引用指向子类对象?
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/12002682.html
Copyright © 2011-2022 走看看