Pots

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 31   Accepted Submission(s) : 14
Special Judge
Problem Description

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  1. FILL(i)        fill the pot i (1 ≤ ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. POUR(i,j)    pour from pot i to pot j; after this operation either the pot j is full (and there may be some water left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).

Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.

 
Input

On the first and only line are the numbers AB, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).

 
Output

The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.

 
Sample Input
3 5 4
 
Sample Output
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)
 
Source
PKU

题意:给出不定数量的样例,每个样例一行,有三个整数,a,b,c,a和b代表两个杯子的容量,c是希望得到的液体体积,一开始两个杯子都是空的,如果利用两个杯子可以倒出c则输出最小的步数和倒出c的步骤;

对两个杯子可以进行以下操作:

FILL(i):装满第i个杯子;

POUR(i,j):从第i个杯子向第j个杯子中倒水;

DROP(i):清空第i个杯子;

思路:

利用BFS进行搜索,求出最小部属并输出;注意对于每一个状态都可能有六种操作,在进行每一种操作前都要进行判断该操作可以进行吗。

AC代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath> using namespace std;
struct node
{
int aa;
int bb;
int sgin;//父亲节点
int sp;//父亲节点到该点的操作
};
int a,b,c;
int ff=;
node sk[];//队列
bool sg[][];//记录节点的访问属性
int kiss[];//记录操作 void s1(node &s,int m)//操作1:把a倒满
{
s.aa=a;
s.sgin=m;//记录下父亲节点的位置
s.sp=;//记录下有父亲节点到达该点的操作
}
void s2(node &s,int m)//操作2:把b倒满
{
s.bb=b;
s.sgin=m;
s.sp=;
}
void s3(node &s,int m)//操作3:把a清空
{
s.aa=;
s.sgin=m;
s.sp=;
}
void s4(node &s,int m)//操作4:把b清空
{
s.bb=;
s.sgin=m;
s.sp=;
}
void s5(node &s,int m)//操作5:从a中向b中到溶液
{
if(s.aa+s.bb<=b){
s.bb+=s.aa;
s.aa=;
s.sgin=m;
s.sp=;
}
else{
s.aa=s.aa-(b-s.bb);
s.bb=b;
s.sgin=m;
s.sp=;
}
}
void s6(node &s,int m)//操作6:从b中向a中到溶液
{
if(s.bb+s.aa<=a){
s.aa+=s.bb;
s.bb=;
s.sgin=m;
s.sp=;
}
else{
s.bb=s.bb-(a-s.aa);
s.aa=a;
s.sgin=m;
s.sp=;
}
} int ss(node x)//找出步骤
{
while(){
if(x.sp==)
break;
kiss[ff++]=x.sp;
x=sk[x.sgin];
}
return ;
} int bfs()
{
sk[].aa=;//初始化条件
sk[].bb=;
sk[].sgin=;
sk[].sp=;//挑出步骤的跳出条件
sg[][]=true;
int le=,ri=;
while(le<ri){
node x=sk[le];
if(x.aa==c||x.bb==c){//利用两个杯子倒出了容量c
ss(x);
return ;//利用两个杯子可以倒出容量c,则返回1
}
if(x.aa!=a){//进行操作1时要判断a是否是满的,如果a是满的则不可以进行操作1
s1(x,le);
if(sg[x.aa][x.bb]==false){//操作1进行后,产生了新的点,检验该点被访问你过吗,若果该点别访问过着不可以插入到队列了面
sk[ri++]=x;
sg[x.aa][x.bb]=true;
}
x=sk[le];
}
if(x.bb!=b){//如果b是满的则不可以进行操作2
s2(x,le);
if(sg[x.aa][x.bb]==false){//操作2进行后,产生了新的点,检验该点被访问你过吗,若果该点别访问过着不可以插入到队列了面
sk[ri++]=x;
sg[x.aa][x.bb]=true;
}
x=sk[le];
}
if(x.aa!=){//如果a是空的则不可以进行操作3
s3(x,le);
if(sg[x.aa][x.bb]==false){//操作3进行后,产生了新的点,检验该点被访问你过吗,若果该点别访问过着不可以插入到队列了面
sk[ri++]=x;
sg[x.aa][x.bb]=true;
}
x=sk[le];
}
if(x.bb!=){//如果b是空的则不可以进行操作4
s4(x,le);
if(sg[x.aa][x.bb]==false){//操作4进行后,产生了新的点,检验该点被访问你过吗,若果该点别访问过着不可以插入到队列了面
sk[ri++]=x;
sg[x.aa][x.bb]=true;
}
x=sk[le];
}
if(x.aa!=){//如果a是空的则不可以进行操作5
s5(x,le);
if(sg[x.aa][x.bb]==false){//操作5进行后,产生了新的点,检验该点被访问你过吗,若果该点别访问过着不可以插入到队列了面
sk[ri++]=x;
sg[x.aa][x.bb]=true;
}
x=sk[le];
}
if(x.bb!=){//如果b是空的则不可以进行操作6
s6(x,le);
if(sg[x.aa][x.bb]==false){//操作6进行后,产生了新的点,检验该点被访问你过吗,若果该点别访问过着不可以插入到队列了面
sk[ri++]=x;
sg[x.aa][x.bb]=true;
}
}
le++;
}
return ;//利用两个杯子不可以倒出容量c,则返回0;
} int main()
{
// freopen("input.txt","r",stdin);
while(cin>>a>>b>>c){
memset(sg,false,sizeof(sg));
memset(kiss,,sizeof(kiss));
ff=;
int skn=bfs();
if(skn==){
cout<<ff<<endl;
ff--;
while(ff>=)
{
if(kiss[ff]==){
cout<<"FILL(1)"<<endl;
}
if(kiss[ff]==){
cout<<"FILL(2)"<<endl;
}
if(kiss[ff]==){
cout<<"DROP(1)"<<endl;
}
if(kiss[ff]==){
cout<<"DROP(2)"<<endl;
}
if(kiss[ff]==){
cout<<"POUR(1,2)"<<endl;
}
if(kiss[ff]==){
cout<<"POUR(2,1)"<<endl;
}
ff--;
}
}
else{
cout<<"impossible"<<endl;
}
}
return ;
}

网上他人的代码:

 #include<iostream>
#include<string>
#include<cstdio>
#include<cstring> using namespace std; const int maxn=; string op[]={"","FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(2,1)","POUR(1,2)"}; int l,r;
int a,b,c;
int vis[maxn][maxn],step[maxn*maxn]; struct node{
int x,y;
int opr;
int pre;
}info[maxn*maxn]; void Solve(int x,int y,int opr){
if(vis[x][y])
return ;
vis[x][y]=;
info[r].x=x;
info[r].y=y;
info[r].opr=opr;
info[r].pre=l;
r++;
} void Print(){
int ans=;
while(l!=){
step[ans++]=info[l].opr;
l=info[l].pre;
}
printf("%d\n",ans);
for(int i=ans-;i>=;i--)
cout<<op[step[i]]<<endl;
} void BFS(){
info[].x=;
info[].y=;
vis[][]=;
l=;
r=;
int tx,ty;
while(l!=r){
if(info[l].x==c || info[l].y==c){
Print();
return ;
} tx=a;
ty=info[l].y;
Solve(tx,ty,); tx=info[l].x;
ty=b;
Solve(tx,ty,); tx=;
ty=info[l].y;
Solve(tx,ty,); tx=info[l].x;
ty=;
Solve(tx,ty,); tx=info[l].x+min(a-info[l].x,info[l].y);
ty=info[l].y-min(a-info[l].x,info[l].y);
Solve(tx,ty,); tx=info[l].x-min(b-info[l].y,info[l].x);
ty=info[l].y+min(b-info[l].y,info[l].x);
Solve(tx,ty,); l++;
}
if(l>=r)
printf("impossible\n");
} int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d%d%d",&a,&b,&c)){
memset(vis,,sizeof(vis));
BFS();
}
return ;
}

Pots(BFS)的更多相关文章

  1. poj3414 Pots (BFS)

    Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12198   Accepted: 5147   Special J ...

  2. 【POJ - 3414】Pots(bfs)

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

  3. POJ-3414 Pots (BFS)

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

  4. poj 3414 Pots ( bfs )

    题目:http://poj.org/problem?id=3414 题意:给出了两个瓶子的容量A,B, 以及一个目标水量C, 对A.B可以有如下操作: FILL(i)        fill the ...

  5. poj3414 Pots(BFS)

    题目链接 http://poj.org/problem?id=3414 题意 有两个杯子,容量分别为A升,B升,可以向杯子里倒满水,将杯子里的水倒空,将一个杯子里的水倒到另一个杯子里,求怎样倒才能使其 ...

  6. POJ 3414 Pots(罐子)

    POJ 3414 Pots(罐子) Time Limit: 1000MS    Memory Limit: 65536K Description - 题目描述 You are given two po ...

  7. 深搜(DFS)广搜(BFS)详解

    图的深搜与广搜 一.介绍: p { margin-bottom: 0.25cm; direction: ltr; line-height: 120%; text-align: justify; orp ...

  8. 【算法导论】图的广度优先搜索遍历(BFS)

    图的存储方法:邻接矩阵.邻接表 例如:有一个图如下所示(该图也作为程序的实例): 则上图用邻接矩阵可以表示为: 用邻接表可以表示如下: 邻接矩阵可以很容易的用二维数组表示,下面主要看看怎样构成邻接表: ...

  9. 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现

    1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...

随机推荐

  1. js的特殊运算符

    1)三元条件运算符: c是一个布尔值,当c为true的时候,取冒号左边a的值,否取冒号右边的b的值: 2)逗号运算符: 值从左到右依次计算,取最右边的,例如例子里的val,会取最右边的值3: 特殊运算 ...

  2. ap143 led修改

    以前的硬件版本只使用了一个eth口,新的板子增加了一个eth口,并且增加了响应的通信时使用的灯. led修改涉及到一下的内容: (1)led 对应的gpio口(这个需要根据原理图来定义) 需要修改的源 ...

  3. Java Socket编程基础(1)

    参考资料: <Java网络编程精解> 孙卫琴 一.socket通信简介 什么是socket,简单来说,在linux系统上,进程与进程之间的通信称为IPC,在同一台计算机中,进程与进程之间通 ...

  4. .Net中jQuery.ajax()调用asp.net后台方法 总结

    利用JQuery的$.ajax()调用.Net后台方法有多种方式, 不多说了  直接上代码 前台代码 <script type="text/javascript"> $ ...

  5. javaweb之session过期验证

    session过期判断的基本思想:用户登录成功后,将用户账号信息保存在session中,然后几乎每次执行命令都要经过过滤器,过滤器检查session中是否存在账号,若不存在, 则返回登录页面,反之正常 ...

  6. Hibernate遇到oracle之主键生成策略

    一直用Hibernate+mysql,感觉Hibernate很好用,也出过什么大问题:这周,公司的产品要部署到Orecle,虽然产品号称支持Oracle但是我自己知道,这个产品压根儿就没在Oracle ...

  7. redhat 安装配置samba实现win共享linux主机目录

    [转]http://blog.chinaunix.net/uid-26642180-id-3135941.html redhat 安装配置samba实现win共享linux主机目录 2012-03-1 ...

  8. SQLServer 重建索引前后对比

    在做维护项目的时,我们经常会遇到索引维护的问题,通过语句,我们就可以判断某个表的索引是否需要重建. 执行一下语句:先分析表的索引 分析表的索引建立情况:DBCC showcontig('Table') ...

  9. JavaScript DOM编程艺术-学习笔记(第十章、第十一章)

    第十章 1.动画中,因为js的效率高,所以看不见过渡效果 2.题外话:①国外人写书,总是先感谢一遍亲朋好友,最后感谢自己的家人. 3."除非允许用户'冻结'移动的内容,否则应该避免让内容在页 ...

  10. libimobiledevice命令

    Mac 安装 1. 安装HomeBrew ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/m ...