题目链接: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


 #include <iostream>
#include <cstring>
#include<vector>
#include<string>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>
using namespace std; #define inf (1LL << 31) - 1
#define rep(i,j,k) for(int i = (j); i <= (k); i++)
#define rep__(i,j,k) for(int i = (j); i < (k); i++)
#define per(i,j,k) for(int i = (j); i >= (k); i--)
#define per__(i,j,k) for(int i = (j); i > (k); i--) int A_L, B_L, C_L; //六种操作,都先预处理好
string op[] = { "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)",
"POUR(1,2)", "POUR(2,1)" };
//其实算一个类用
struct node{ int A,B; //A,B杯子中水升数情况
vector<string > str; //记录操作
// int l;
node(int a = , int b = ){ A = a; B = b; } void Fill(int num){ //(1)操作处理
if (num == ) A = A_L;
else B = B_L;
} void Drop(int num){ //(2)操作处理
if (num == ) A = ;
else B = ;
} void Pour(int num){ //(3)操作处理
if (num == ){
int tmp = A;
A -= (A >= B_L - B ? (B_L - B) : A);
B = (tmp >= B_L - B ? B_L : B + tmp);
}
else{
int tmp = B;
B -= (B >= A_L - A ? (A_L - A) : B);
A = (tmp >= A_L - A ? A_L : A + tmp);
}
} }; void fun(string str){
cout << str << endl;
} void bfs(){ map<pair<int, int>, bool> mp; //记录<A,B>的情况 node init;
/*
pair<int,int > p (init.A, init.B);
mp[p] = true;
*/ queue<node> que;
que.push(init); while (!que.empty()){ node key = que.front();
que.pop(); pair<int, int> o( key.A, key.B );
if (mp[o]) continue; //判断这个<A,B>有误出现过,出现了就不继续下去了
mp[o] = true; //没出现过,标记一下 //六种情况
rep(p, , ){ node tmp = key; if (p == ) tmp.Fill(),tmp.str.push_back(op[]);
else if (p == ) tmp.Fill(), tmp.str.push_back(op[]);
else if (p == ) tmp.Drop(), tmp.str.push_back(op[]);
else if (p == ) tmp.Drop(), tmp.str.push_back(op[]);
else if (p == ) tmp.Pour(), tmp.str.push_back(op[]); //pour(1,2)
else if (p == ) tmp.Pour(), tmp.str.push_back(op[]); //pour(2,1) //其中一个满足即可
if (tmp.A == C_L || tmp.B == C_L){
cout << (int)tmp.str.size() << endl; //遍历tmp的vector
for_each(tmp.str.begin(), tmp.str.end(), fun); return;
} o = make_pair(tmp.A, tmp.B); //也是判断下新的<A,B>是否出现过
if (!mp[o]) que.push(tmp); //出现过,不再压入队列
}
} //无法得出C
cout << "impossible" << endl; } int main(){ ios::sync_with_stdio(false);
cin.tie(); cin >> A_L >> B_L >> C_L; //记录A的最大容量,B的最大容量,标准C
bfs(); return ;
}

kuangbin专题 专题一 简单搜索 Pots POJ - 3414的更多相关文章

  1. Pots(POJ - 3414)【BFS 寻找最短路+路径输出】

    Pots(POJ - 3414) 题目链接 算法 BFS 1.这道题问的是给你两个体积分别为A和B的容器,你对它们有三种操作,一种是装满其中一个瓶子,另一种是把其中一个瓶子的水都倒掉,还有一种就是把其 ...

  2. Pots POJ 3414

    /* *POJ 3414 *简单模板bfs *编程应该为了方便理解,尽量提供接口 */ #include<cstdio> #include<algorithm> #includ ...

  3. kuangbin专题 专题一 简单搜索 Fliptile POJ - 3279

    题目链接:https://vjudge.net/problem/POJ-3279 题意:格子有两面,1表示黑色格子,0表示白色格子,奶牛每次可以踩一个格子,踩到的格子和它周围的上下左右格子都会翻面,也 ...

  4. kuangbin专题总结一 简单搜索

    A - 棋盘问题:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有 ...

  5. Pots POJ - 3414 (搜索+记录路径)

    Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22688   Accepted: 9626   Special J ...

  6. Pots POJ - 3414【状态转移bfs+回溯】

    典型的倒水问题: 即把两个水杯的每种状态视为bfs图中的点,如果两种状态可以转化,即可认为二者之间可以连一条边. 有3种倒水的方法,对应2个杯子,共有6种可能的状态转移方式.即相当于图中想走的方法有6 ...

  7. 搜索入门_简单搜索bfs dfs大杂烩

    dfs题大杂烩 棋盘问题  POJ - 1321 和经典的八皇后问题一样.  给你一个棋盘,只有#区域可以放棋子,同时同一行和同一列只能有一个棋子. 问你放k个棋子有多少种方案. 很明显,这是搜索题. ...

  8. [kuangbin带你飞]专题一 简单搜索

            ID Origin Title 454 / 1008 Problem A POJ 1321 棋盘问题   328 / 854 Problem B POJ 2251 Dungeon Ma ...

  9. poj 3279 Fliptile (简单搜索)

    Fliptile Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16558   Accepted: 6056 Descrip ...

随机推荐

  1. C# 事件详解

    1.事件的本质是什么 答:事件是委托的包装器,就像属性是字段的包装器一样 2.为什么有了委托还有有事件 委托可以被访问就可以被执行,事件则只能在类的内部执行 3.事件要怎么声明 a.明一个委托 //委 ...

  2. GlusterFS集群文件系统研究(负载均衡的最常用办法) good

    http://blog.csdn.net/liuaigui/article/details/6284551 http://blog.csdn.net/liuaigui/article/details/ ...

  3. Android零基础入门第28节:轻松掌握RelativeLayout相对布局

    原文:Android零基础入门第28节:轻松掌握RelativeLayout相对布局 在前面三期中我们对LinearLayout进行了详细的解析,LinearLayout也是我们用的比较多的一个布局. ...

  4. Android零基础入门第50节:StackView卡片堆叠

    原文:Android零基础入门第50节:StackView卡片堆叠 上一期学习了AdapterViewFilpper的使用,你已经掌握了吗?本期开始学习StackView的使用. 一.认识StackV ...

  5. 【Windows10 IoT开发系列】开发人员模式设置

    原文:[Windows10 IoT开发系列]开发人员模式设置  声明:本文转自微软Windows 开发人员中心(https://msdn.microsoft.com/library/windows/ ...

  6. 『SHELL』--SHELL脚本执行方式(转)

    Shell脚本的执行方式: 注明:wd代表“脚本保存的目录” 1.fork 语法:/wd/shell.sh fork是最普通的, 就是直接在脚本里面用/wd/shell.sh来调用shell.sh这个 ...

  7. Qt4学习笔记 (7) 本篇说一下Qt对于脚本的支持, 即QtScript模块.

    本篇说一下Qt对于脚本的支持, 即QtScript模块. Qt支持的脚本基于ECMAScript脚本语言, 这个东西又是javascript, jscript的基础. 所以, 一般只要学过javasc ...

  8. Delphi产生任务栏图标【TNotifyIconData】

    一.新建一个应用程序:File->New Applicaton 在Interface部分要放在Uses Message之后,定义一个消息常量:const WM_NID=WM_USER+1000; ...

  9. Bootstrap3.0学习(一)

    Bootstrap是Twitter退出的一个开源的用于前端开发的工具包.它由Twitter的设计师Mark Otto和Jacob Thornton合作开发,是一个CSS/HTML框架.Bootstra ...

  10. Gps坐标有效性判定

    百科:纬度 是指某点与地球球心的连线和地球赤道面所成的线面角,其数值在0至90度之间.位于赤道以北的点的纬度叫北纬,记为N:位于赤道以南的点的纬度称南纬,记为S. var regex = new Re ...