Pots POJ - 3414 (搜索+记录路径)
pots
description you are given two pots, having the volume of a and b liters respectively. the following operations can be performed:
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 a, b, 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
northeastern europe 2002, western subregion
|
题意:
有二个水壶,对水壶有三种操作:
1)fill(i),将i水壶的水填满;
2)drop(i),将水壶i中的水全部倒掉;
3)pour(i,j)将水壶i中的水倒到水壶j中,若水壶 j 满了,则 i 剩下的就不倒了,问进行多少步操作,并且怎么操作,输出操作的步骤,两个水壶中的水可以达到c这个水量。如果不可能则输出impossible。初始时两个水壶是空的,没有水。
思路:
模拟一下,然后如果当前的状态已经出现过了就说明不可以这样子,必须要用其他操作,这个和poj3087的题目有点像,这里还需要储存一个路径,这个和poj3984有点像,poj3984之前的博客里面用了递归的方式输出路径,这一回用了栈,两种方法应该都可以做的,具体的看代码吧,注释已经很清楚了
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<cstdlib> #include<queue> #include<set> #include<stack> #include<vector> using namespace std; #define inf 0x3f3f3f3f #define eps 1e-10 #define pi acos(-1.0) #define _e exp(1.0) #define ll long long const int maxn=110; struct cup { int x,y; //a和b的当前水的状态 int step; int flag; //标记操作,是操作几 cup *pre; //记录路径的玩意儿 }; queue<cup>que; stack<int>r; int a,b,e; int vis[maxn][maxn]={0}; //记录当前的状态是否到达过 int ans; void bfs(int x,int y) { cup c; cup t[317]; //目前瓶子里剩余的水量 c.x=0; c.y=0; c.flag=0; c.pre=null; c.step=0; que.push(c); vis[x][y]=1; int count=-1; while(!que.empty()) { count++; t[count]=que.front(); que.pop(); for(int i=1;i<=6;i++) { switch(i) { case 1: //fill a c.x=a; c.y=t[count].y; c.flag=1; break; case 2: //fill b c.x=t[count].x; c.y=b; c.flag=2; break; case 3: //drop a c.x=0; c.y=t[count].y; c.flag=3; break; case 4: //drop b c.x=t[count].x; c.y=0; c.flag=4; break; case 5: //pour a to b if(t[count].x>b-t[count].y) //a可以装满b { c.x=t[count].x-(b-t[count].y); c.y=b; } else //a不能装满b { c.x=0; c.y=t[count].y+t[count].x; } c.flag=5; break; case 6: //pour b to a if(t[count].y>a-t[count].x) //b可以装满a { c.y=t[count].y-(a-t[count].x); c.x=a; } else //b不可以装满a { c.x=t[count].x+t[count].y; c.y=0; } c.flag=6; break; } if(vis[c.x][c.y]) continue; vis[c.x][c.y]=1; c.step=t[count].step+1; c.pre=&t[count]; if(c.x==e || c.y==e) { ans=c.step; while(c.pre) { r.push(c.flag); c=*c.pre; } return; } que.push(c); } } } void print() { while(!r.empty()) { int i=r.top(); r.pop(); switch(i) { case 1:cout<<"fill(1)"<<endl;break; case 2:cout<<"fill(2)"<<endl;break; case 3:cout<<"drop(1)"<<endl;break; case 4:cout<<"drop(2)"<<endl;break; case 5:cout<<"pour(1,2)"<<endl;break; case 6:cout<<"pour(2,1)"<<endl;break; } } } int main() { cin>>a>>b>>e; bfs(0,0); if(ans==0) cout<<"impossible"<<endl; else { cout<<ans<<endl; print(); } return 0; }