<题目链接>

题目大意:

有两个容量的空杯子,能够对这两个空杯子进行三种操作:

分别是fill(a),装满a杯子;

drop(a),倒空a杯子;

pour(a,b),将a杯子中的水倒入b杯子中;

现在问你,是否能够通过这三种操作,使得这两个杯子中至少有一个杯子中含有c体积的水,如果不行,输出“impossible”,如果可以,输出操作的步数,以及每一步的具体操作。

解题分析:

此题与一道输出路径的很相像,只不过那道题是输出每一次操作对应的点的状态,而此题是要输出具体的操作。不难想到,我们依然可以记录下BFS路径上点的状态,然后根据这个点和上一个点的状态差距推导出它们之间的具体操作。

#include <cstdio>
#include <cstring> int v[],m; const int maxn=;
int vis[][];
int flag; struct node{
int val[];
int step;
int pre; //记录上一个点在que[]数组中的位置
node(int a=,int b=,int c=,int d=-){
val[]=a,val[]=b,step=c,pre=d;
}
}que[maxn]; void fill(node &now,int a){
now.val[a]=v[a];
} void drop(node &now,int a){
now.val[a]=;
} void pour(node &now,int a,int b){
int sum=now.val[a]+now.val[b];
if(sum>v[b]){
now.val[b]=v[b];
now.val[a]=sum-v[b];
}
else{
now.val[b]=sum;
now.val[a]=;
}
} void print(node tmp){ //根据相邻两个点的状况来推断操作
if(tmp.pre!=-){
print(que[tmp.pre]);
}
if(tmp.pre!=-){ //如果这个点和上一个点之间有操作,就可以将这个操作求出来
node prenode=que[tmp.pre];
node cal=prenode;
pour(cal,,);
if(tmp.val[]==v[]&&tmp.val[]==prenode.val[]){
printf("FILL(1)\n");
}
else if(tmp.val[]==v[]&&tmp.val[]==prenode.val[]){
printf("FILL(2)\n");
}
else if(tmp.val[]==&&tmp.val[]==prenode.val[]){
printf("DROP(1)\n");
}
else if(tmp.val[]==&&tmp.val[]==prenode.val[]){
printf("DROP(2)\n");
}
else if(cal.val[]==tmp.val[]&&cal.val[]==tmp.val[]){
printf("POUR(1,2)\n");
}
else{
printf("POUR(2,1)\n");
}
}
} void bfs(){
memset(vis,,sizeof(vis));
int front=,end=;
vis[][]=;
que[end++]=node(,,,-);
while(front<end){
node now=que[front];
front++;
if(now.val[]==m||now.val[]==m){
flag=true;
printf("%d\n",now.step);
print(now);
return;
}
for(int i=;i<=;i++){ //装满
node tmp=now; //注意,这里为了防止now发生改变,从而对后面的操作产生影响,所以这里是对tmp进行操作
fill(tmp,i);
if(!vis[tmp.val[]][tmp.val[]]){
vis[tmp.val[]][tmp.val[]]=;
que[end++]=node(tmp.val[],tmp.val[],tmp.step+,front-);
}
}
for(int i=;i<=;i++){ //倒空
node tmp=now;
drop(tmp,i);
if(!vis[tmp.val[]][tmp.val[]]){
vis[tmp.val[]][tmp.val[]]=;
que[end++]=node(tmp.val[],tmp.val[],tmp.step+,front-);
}
}
for(int i=;i<=;i++){ //i向j注水
for(int j=;j<=;j++){
if(i==j)continue;
node tmp=now;
pour(tmp,i,j);
if(!vis[tmp.val[]][tmp.val[]]){
vis[tmp.val[]][tmp.val[]]=;
que[end++]=node(tmp.val[],tmp.val[],tmp.step+,front-);
}
}
}
}
} int main(){
while(scanf("%d %d %d",&v[],&v[],&m)!=EOF){
flag=false;
bfs();
if(!flag){
printf("impossible\n");
}
}
return ;
}

2018-08-29

POJ 3414 Pot (输出路径)【BFS】的更多相关文章

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

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

  2. POJ 3414 Pots 记录路径的广搜

    Description You are given two pots, having the volume of A and B liters respectively. The following ...

  3. HDU 1043 Eight 【经典八数码输出路径/BFS/A*/康托展开】

    本题有写法好几个写法,但主要思路是BFS: No.1 采用双向宽搜,分别从起始态和结束态进行宽搜,暴力判重.如果只进行单向会超时. No.2 采用hash进行判重,宽搜采用单向就可以AC. No.3 ...

  4. 【POJ - 3414】Pots(bfs)

    Pots 直接上中文 Descriptions: 给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作 FILL(i)        将第i个容器从水龙头里装满(1 ≤ i ≤ 2); DRO ...

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

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

  6. 广搜+输出路径 POJ 3414 Pots

    POJ 3414 Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13547   Accepted: 5718   ...

  7. poj 3414 Pots 【BFS+记录路径 】

    //yy:昨天看着这题突然有点懵,不知道怎么记录路径,然后交给房教了,,,然后默默去写另一个bfs,想清楚思路后花了半小时写了120+行的代码然后出现奇葩的CE,看完FAQ改了之后又WA了.然后第一次 ...

  8. (poj)3414 Pots (输出路径的广搜)

    Description You are given two pots, having the volume of A and B liters respectively. The following ...

  9. POJ 3414 Pots【bfs模拟倒水问题】

    链接: http://poj.org/problem?id=3414 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22009#probl ...

随机推荐

  1. Mac下压力测试工具siege

    安装: brew install siege 用法: siege -c 并发数 -t 运行测试时间 URL 如: siege -c 1000 -t 5S URL 这里要注意的是-t后面的时间要带单位, ...

  2. window.location详解

    window.location对象常用属性 location.hostname 返回 web 主机的域名 location.host 返回 web 主机的域名(包含端口) location.pathn ...

  3. C. Trailing Loves (or L'oeufs?)

    题目链接:http://codeforces.com/contest/1114/problem/C 题目大意:给你n和b,让你求n的阶乘,转换成b进制之后,有多少个后置零. 具体思路:首先看n和b,都 ...

  4. python内置模块之unittest测试(五)

    系列文章 python模块分析之random(一) python模块分析之hashlib加密(二) python模块分析之typing(三) python模块分析之logging日志(四) pytho ...

  5. Git入门——远程仓库及分支管理

    关于本地版本库的操作,请见:Git入门--本地版本库操作 本篇提到的所有命令: 小结 前面提到,Git相对于传统的SVN有着很大的优势,其中之一就在于集中式系统中,版本库只能存在于中央服务器上:而在G ...

  6. AT91RM9200---SMC简介

    1.前言 SMC(Static Memory Controller)Atmel 9200静态存储控制器的简称,它可以产生信号来控制外部静态存储和外设.SMC可通过编程寄存器来进行配置. 它有8路片选和 ...

  7. 程序执行的过程分析--【sky原创】

    程序执行的过程:     比如我们要执行3 + 2   程序计数器(PC) = 指令地址 指令寄存器(IR) = 正在执行的命令 累加器(AC) = 临时存储体   那么实际上执行了三条指令 每条指令 ...

  8. 生成ansible-playbook的yaml文件的代码(字典排序问题无法解决)

    import yaml import collections def add_task(): return None def add_vars(): return None def add_handl ...

  9. mysql主从配置 转自http://www.cnblogs.com/sustudy/p/4174189.html

    1.确保主数据库与从数据库一模一样. 例如:主数据库里的a的数据库里有b,c,d表,那从数据库里的就应该有一个模子刻出来的a的数据库和b,c,d表 2.在主数据库上创建同步账号. GRANT REPL ...

  10. css 悬浮框

    <style>    .xfk {        display: block;        position: fixed;        top: 150px;        lef ...