poj 3414 Pots(认为是一道很好的bfs题目)
来源:互联网 发布:php简单论坛源码 编辑:程序博客网 时间:2024/06/12 00:08
Description
You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:
- FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;
- DROP(i) empty the pot i to the drain;
- POUR(i,j) pour from pot i to pot j; after this operation either the potj is full (and there may be some water left in the pot i), or the poti 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 exactlyC liters of water in one of the pots.
Input
On the first and only line are the numbers A, B, andC. 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 operationsK. 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
6FILL(2)POUR(2,1)DROP(1)POUR(2,1)FILL(2)POUR(2,1)
/*题目大意: 有二个水壶,对水壶有三种操作: 1)FILL(i),将i水壶的水填满; 2)DROP(i),将水壶i中的水全部倒掉; 3)POUR(i,j)将水壶i中的水倒到水壶j中,若水壶 j 满了,则 i 剩下的就不倒了;
问进行多少步操作,并且怎么操作,输出操作的步骤,两个水壶中至少其中一个壶的水可以达到C这个水量。如果不可能则输出impossible。
初始时两个水壶是空的,没有水。 样例中的1代表i,2代表j;拿样例举个栗子:input:3 5 4 //i(用1表示)水壶的容量是3,j(用2表示)水壶的容量是5,要求两个水壶中至少其中一个壶的水可以达到4这个水量0utput:6//需要经过的步数FILL(2) //把j水壶填满,此时j==5;POUR(2,1)//把j水壶中的水倒到i水壶,则此时i==3,j==5-3==2DROP(1)//倒掉i水壶中的水,则此时i==0,j==2POUR(2,1)//把j水壶中的水倒到i水壶,则此时i==2,j==0FILL(2)//把j水壶填满,此时j==5;POUR(2,1)//把j水壶中的水倒到i水壶,则此时i==3,j==5-1==4(满足条件)算法分析:1. 找出状态转移方程. 2. 难点是判重和状态的保存. 判重用的是visited[x][y]二维数组, A为容量x, B为容量y时标记已访问;当再次A为容量x, B为容量y时,不再重复搜索(剪枝). 至于状态的保存用的是一个结构体 struct Step{ int cnt; //走的步数 int prex, prey; //前一步的i,j分别的容量prex, prey int preflag; //前一步到本步骤执行的操作标志};
后面的实现具体看代码.
*/
#include<iostream>#include<queue>#include<stack>#include<cstring>using namespace std;int a,b,c;struct pots//存储每一步当前水壶i,j的水量{ int x,y; pots(int xx,int yy){x=xx;y=yy;}};struct Step{ int cnt;//走的步数 int prex,prey;//前一步水壶i,j的水量 int preflag;//前一步到本步骤执行的操作标志};bool visited[102][102];//判断“i的水量为x, j的水量为y”时是否已访问过;当再次i的水量为x, j的水量为y时,不再重复搜索(剪枝)Step step[102][102];queue<pots>q;int endx,endy;void savestate(int x,int y,int prex,int prey,int flag) //此函数用来保存当前这一步的所有状态(包括 步数,前一步水壶i,j的水量,前一步到本步骤执行的操作标志){ q.push(pots(x,y)); step[x][y].cnt=step[prex][prey].cnt+1; step[x][y].prex=prex; step[x][y].prey=prey; step[x][y].preflag=flag;}int bfs()//搜索{ memset(visited,0,sizeof(visited)); memset(step,0,sizeof(step)); q.push(pots(0,0)); while(q.size()) { pots v=q.front(); q.pop(); if(v.x==c||v.y==c)//如果满足条件,终止搜索 { endx=v.x; endy=v.y; break; } visited[v.x][v.y]=1; if(v.x<a&&!visited[a][v.y]) savestate(a,v.y,v.x,v.y,0);//fill a if(v.y<b&&!visited[v.x][b]) savestate(v.x,b,v.x,v.y,1);//fill b if(v.x>0&&!visited[0][v.y]) savestate(0,v.y,v.x,v.y,2);//drop a if(v.y>0&&!visited[v.x][0]) savestate(v.x,0,v.x,v.y,3);//drop b if(v.x>0)//pour a to b { if(v.x<b-v.y&&!visited[0][v.x+v.y]) savestate(0,v.x+v.y,v.x,v.y,4); else if(v.x>=b-v.y&&!visited[v.x-(b-v.y)][b]) savestate(v.x-(b-v.y),b,v.x,v.y,5); } if(v.y>0)//pour b to a { if(v.y<a-v.x&&!visited[v.x+v.y][0]) savestate(v.x+v.y,0,v.x,v.y,6); else if(v.y>=a-v.x&&!visited[a][v.y-(a-v.x)]) savestate(a,v.y-(a-v.x),v.x,v.y,7); } } return step[endx][endy].cnt;//返回步数}void findpath()//输出路径{ stack<int>s;//用栈来存储,很巧妙! int x=endx; int y=endy; while(!(x==0&&y==0)) { s.push(step[x][y].preflag); int tempx=step[x][y].prex; int tempy=step[x][y].prey; x=tempx;y=tempy; } while(s.size()) { int v=s.top(); s.pop(); switch(v) { case 0: cout<<"FILL(1)"<<endl;break; case 1: cout<<"FILL(2)"<<endl;break; case 2: cout<<"DROP(1)"<<endl;break; case 3: cout<<"DROP(2)"<<endl;break; case 4: case 5: cout<<"POUR(1,2)"<<endl;break; case 6: case 7: cout<<"POUR(2,1)"<<endl;break; } }}int main(){ cin>>a>>b>>c; int ret=bfs(); if(ret) { cout<<ret<<endl; findpath(); } else cout<<"impossible"<<endl; return 0;}
- poj 3414 Pots(认为是一道很好的bfs题目)
- POJ 3414 Pots BFS
- POJ 3414 Pots(BFS)
- poj 3414 Pots bfs
- poj 3414 Pots BFS
- poj 3414 Pots BFS
- poj 3414 Pots (bfs)
- BFS-POJ-3414-Pots
- POJ 3414 Pots BFS
- POJ 3414-Pots(BFS)
- poj-3414 Pots BFS
- poj 3414 Pots bfs
- POJ 3414 POTS BFS
- poj 3414 (POTS) (BFS)
- POJ 3414 Pots (BFS)
- POJ - 3414 Pots(BFS)
- POJ 3414 Pots (BFS)
- 【Poj 3414】 Pots BFS
- Navicat 用ssh通道连接时总是报错 (报错信息:SSH:expected key exchange group packet form serve
- hdu 6058 Kanade's sum(思维)
- 【Java学习笔记】27:文件的随机访问&对象流
- Java中的集合框架概念
- Hibernate利用save()方法时报mysql语法错误
- poj 3414 Pots(认为是一道很好的bfs题目)
- js 空数组直接赋值与push
- zoj3961(区间问题)
- #if、#ifdef、#if defined之间的区别
- JAVASCRIPT
- mysql查询表里的重复数据方法:
- Java读取文件
- FastJson--常用方法总结
- 创建型模式—建造者模式