zoukankan      html  css  js  c++  java
  • kuangbin专题 专题一 简单搜索 Pots POJ

    题目链接:https://vjudge.net/problem/POJ-3414

    题意:给你两个杯子,分别容量为A(1),B(2)和一个C,C是需要经过下列操作,得到的一个升数。
    (1) FILL(i) :把编号为i的杯子中水灌满
    (2)DROP(i):把编号为i的杯子中水全部倒了
    (3)POUR(i,j):把编号为i的杯子中的水倒入编号为j的杯子中,如果编号j杯子中水满了,编号i杯子水就不继续倒了
    问:能不能经过有限次(1)(2)(3)操作,得到A,B中其中一个满足C升的水就可以,可以的话输出最少次数并把操作输出,否则输出“impossble”

    思路:最少,容易想到bfs,加上倒水过程的模拟,也就6种情况,模拟操作预处理之后,后面会变得很好写,其中的过程,看代码注释吧。
    补:我们可以把A,B中升数情况给记录下,出现过的<A,B>就不需要再次bfs了,不然应该会TLE


      1 #include <iostream>
      2 #include <cstring>
      3 #include<vector>
      4 #include<string>
      5 #include <cmath>
      6 #include <map>
      7 #include <queue>
      8 #include <algorithm>
      9 using namespace std;
     10 
     11 #define inf (1LL << 31) - 1
     12 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
     13 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
     14 #define per(i,j,k) for(int i = (j); i >= (k); i--)
     15 #define per__(i,j,k) for(int i = (j); i > (k); i--)
     16 
     17 int A_L, B_L, C_L;
     18 
     19 //六种操作,都先预处理好
     20 string op[6] = { "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)",
     21                 "POUR(1,2)", "POUR(2,1)" };
     22 //其实算一个类用
     23 struct node{
     24 
     25     int A,B; //A,B杯子中水升数情况
     26     vector<string > str; //记录操作
     27 //    int l;
     28     node(int a = 0, int b = 0){ A = a; B = b; }
     29 
     30     void Fill(int num){ //(1)操作处理
     31         if (num == 1) A = A_L;
     32         else B = B_L;
     33     }
     34         
     35     void Drop(int num){ //(2)操作处理
     36         if (num == 1) A = 0;
     37         else B = 0;
     38     }
     39 
     40     void Pour(int num){ //(3)操作处理
     41         if (num == 1){
     42             int tmp = A;
     43             A -= (A >= B_L - B ? (B_L - B) : A);
     44             B = (tmp >= B_L - B ? B_L : B + tmp);
     45         }
     46         else{
     47             int tmp = B;
     48             B -= (B >= A_L - A ? (A_L - A) : B);
     49             A = (tmp >= A_L - A ? A_L : A + tmp);
     50         }
     51     }
     52 
     53 };
     54 
     55 void fun(string str){
     56     cout << str << endl;
     57 }
     58 
     59 void bfs(){
     60 
     61     map<pair<int, int>, bool> mp;  //记录<A,B>的情况
     62 
     63     node init;
     64     /*
     65     pair<int,int > p (init.A, init.B);
     66     mp[p] = true;
     67     */
     68     
     69     queue<node> que;
     70     que.push(init);
     71 
     72     while (!que.empty()){
     73 
     74         node key = que.front();
     75         que.pop();
     76 
     77         pair<int, int> o( key.A, key.B ); 
     78         if (mp[o]) continue; //判断这个<A,B>有误出现过,出现了就不继续下去了
     79         mp[o] = true; //没出现过,标记一下
     80         
     81         //六种情况
     82         rep(p, 1, 6){
     83             
     84             node tmp = key;
     85 
     86             if (p == 1) tmp.Fill(1),tmp.str.push_back(op[0]);
     87             else if (p == 2) tmp.Fill(2), tmp.str.push_back(op[1]);
     88             else if (p == 3) tmp.Drop(1), tmp.str.push_back(op[2]);
     89             else if (p == 4) tmp.Drop(2), tmp.str.push_back(op[3]);
     90             else if (p == 5) tmp.Pour(1), tmp.str.push_back(op[4]); //pour(1,2)
     91             else if (p == 6) tmp.Pour(2), tmp.str.push_back(op[5]); //pour(2,1)
     92             
     93             //其中一个满足即可
     94             if (tmp.A == C_L || tmp.B == C_L){  
     95                 cout << (int)tmp.str.size() << endl;
     96                 
     97                 //遍历tmp的vector
     98                 for_each(tmp.str.begin(), tmp.str.end(), fun);
     99 
    100                 return;
    101             }
    102 
    103             o = make_pair(tmp.A, tmp.B); //也是判断下新的<A,B>是否出现过
    104             if (!mp[o]) que.push(tmp); //出现过,不再压入队列
    105         }
    106     }
    107 
    108     //无法得出C
    109     cout << "impossible" << endl;
    110 
    111 }
    112 
    113 int main(){
    114 
    115     ios::sync_with_stdio(false);
    116     cin.tie(0);
    117 
    118     cin >> A_L >> B_L >> C_L; //记录A的最大容量,B的最大容量,标准C
    119     bfs();
    120 
    121     return 0;
    122 }



    1
  • 相关阅读:
    下个月去北京了,心如一团乱麻好多事情要解决,但是不知道从哪里开始,还是顺其自然吧,一件件的解决
    C# SQLServer 数据库连接类
    C#页面缓存写法
    从北京站到天通苑怎么走,
    工作描述的介绍|如何写工作描述
    网线制作方法|国标网线制作方法|常用的网线制作方法
    递归删除空文件夹
    如何使用股票行情软件看股票
    正则批量验证函数
    简单的游标更新日期例子
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/11164192.html
Copyright © 2011-2022 走看看